mirror of
https://github.com/taigrr/arduinolibs
synced 2025-01-18 04:33:12 -08:00
Rename Terminal library to Shell library
This commit is contained in:
78
libraries/Shell/LoginShell.cpp
Normal file
78
libraries/Shell/LoginShell.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Southern Storm Software, Pty Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "LoginShell.h"
|
||||
|
||||
/**
|
||||
* \class LoginShell LoginShell.h <LoginShell.h>
|
||||
* \brief Command-line shell access via a login shell.
|
||||
*
|
||||
* This class provides a command-line shell with login support.
|
||||
* The user is prompted for username and password when they connect
|
||||
* and other commands will not be available until the correct credentials
|
||||
* have been supplied.
|
||||
*
|
||||
* \sa Shell
|
||||
*/
|
||||
|
||||
/**
|
||||
* \typedef ShellPasswordCheckFunc
|
||||
* \brief Password checking function for login shells.
|
||||
*
|
||||
* \param username Points to the user name that was supplied at login.
|
||||
* \param password Points to the password that was supplied at login.
|
||||
*
|
||||
* \return Returns zero or greater if the username and password combination
|
||||
* is correct, negative if incorrect.
|
||||
*
|
||||
* The return value is reported to the application as Shell::userid(),
|
||||
* which can be used by the application to restrict the set of commands
|
||||
* that are available to the user, or to restrict the behaviour of
|
||||
* those commands when acting on critical resources.
|
||||
*
|
||||
* Timing can be very important: the check should take the same amount of
|
||||
* time for valid and invalid user identifiers or passwords so that an
|
||||
* attacker cannot gain knowledge about the valid users on the system
|
||||
* based on failed login attempts.
|
||||
*
|
||||
* \relates LoginShell
|
||||
* \sa Shell::userid()
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Constructs a new login shell.
|
||||
*
|
||||
* This constructor must be followed by a call to begin() to specify
|
||||
* the underlying I/O stream.
|
||||
*/
|
||||
LoginShell::LoginShell()
|
||||
: machName(0)
|
||||
, checkFunc(0)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Destroys this login shell.
|
||||
*/
|
||||
LoginShell::~LoginShell()
|
||||
{
|
||||
}
|
||||
52
libraries/Shell/LoginShell.h
Normal file
52
libraries/Shell/LoginShell.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Southern Storm Software, Pty Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef LOGIN_SHELL_h
|
||||
#define LOGIN_SHELL_h
|
||||
|
||||
#include "Shell.h"
|
||||
|
||||
typedef int (*ShellPasswordCheckFunc)(const char *username, const char *password);
|
||||
|
||||
class LoginShell : public Shell
|
||||
{
|
||||
public:
|
||||
LoginShell();
|
||||
virtual ~LoginShell();
|
||||
|
||||
const char *machineName() const { return machName; }
|
||||
void setMachineName(const char *machineName) { machName = machineName; }
|
||||
|
||||
ShellPasswordCheckFunc passwordCheckFunction() const { return checkFunc; }
|
||||
void setPasswordCheckFunction(ShellPasswordCheckFunc function) { checkFunc = function; }
|
||||
|
||||
protected:
|
||||
virtual void beginSession();
|
||||
virtual void printPrompt();
|
||||
virtual void execute();
|
||||
|
||||
private:
|
||||
const char *machName;
|
||||
ShellPasswordCheckFunc checkFunc;
|
||||
};
|
||||
|
||||
#endif
|
||||
1092
libraries/Shell/Shell.cpp
Normal file
1092
libraries/Shell/Shell.cpp
Normal file
File diff suppressed because it is too large
Load Diff
163
libraries/Shell/Shell.h
Normal file
163
libraries/Shell/Shell.h
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Southern Storm Software, Pty Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SHELL_h
|
||||
#define SHELL_h
|
||||
|
||||
#include "Terminal.h"
|
||||
#include <Client.h>
|
||||
|
||||
class Shell;
|
||||
class ShellArguments;
|
||||
class LoginShell;
|
||||
|
||||
#if defined(__arm__)
|
||||
#define SHELL_MAX_CMD_LEN 256
|
||||
#else
|
||||
#define SHELL_MAX_CMD_LEN 64
|
||||
#endif
|
||||
|
||||
typedef void (*ShellCommandFunc)(Shell &shell, int argc, const ShellArguments &argv);
|
||||
|
||||
/** @cond */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
const char *help;
|
||||
ShellCommandFunc func;
|
||||
|
||||
} ShellCommandInfo;
|
||||
|
||||
class ShellCommandRegister
|
||||
{
|
||||
public:
|
||||
inline ShellCommandRegister(const ShellCommandInfo *_info);
|
||||
|
||||
const ShellCommandInfo *info;
|
||||
ShellCommandRegister *next;
|
||||
};
|
||||
|
||||
/** @endcond */
|
||||
|
||||
class Shell : public Terminal
|
||||
{
|
||||
public:
|
||||
Shell();
|
||||
virtual ~Shell();
|
||||
|
||||
bool begin(Stream &stream, size_t maxHistory = 0, Terminal::Mode mode = Serial);
|
||||
bool begin(Client &client, size_t maxHistory = 0, Terminal::Mode mode = Telnet);
|
||||
void end();
|
||||
|
||||
void loop();
|
||||
|
||||
static void registerCommand(ShellCommandRegister *cmd);
|
||||
|
||||
const char *prompt() const { return prom; }
|
||||
void setPrompt(const char *prompt) { prom = prompt; }
|
||||
|
||||
int userid() const { return uid; }
|
||||
void setUserid(int userid) { uid = userid; }
|
||||
|
||||
void help();
|
||||
void exit();
|
||||
|
||||
protected:
|
||||
virtual void beginSession();
|
||||
virtual void printPrompt();
|
||||
virtual void execute();
|
||||
|
||||
private:
|
||||
char buffer[SHELL_MAX_CMD_LEN];
|
||||
size_t curStart;
|
||||
size_t curLen;
|
||||
size_t curMax;
|
||||
char *history;
|
||||
size_t historyWrite;
|
||||
size_t historyRead;
|
||||
size_t historySize;
|
||||
const char *prom;
|
||||
bool isClient;
|
||||
uint8_t lineMode;
|
||||
int uid;
|
||||
unsigned long timer;
|
||||
|
||||
// Disable copy constructor and operator=().
|
||||
Shell(const Shell &other) {}
|
||||
Shell &operator=(const Shell &) { return *this; }
|
||||
|
||||
bool beginShell(Stream &stream, size_t maxHistory, Terminal::Mode mode);
|
||||
bool execute(const ShellArguments &argv);
|
||||
void executeBuiltin(const char *cmd);
|
||||
void clearCharacters(size_t len);
|
||||
void changeHistory(bool up);
|
||||
void clearHistory();
|
||||
|
||||
friend class LoginShell;
|
||||
};
|
||||
|
||||
class ShellArguments
|
||||
{
|
||||
friend class Shell;
|
||||
private:
|
||||
ShellArguments(char *buffer, size_t len);
|
||||
~ShellArguments() {}
|
||||
public:
|
||||
|
||||
int count() const { return argc; }
|
||||
const char *operator[](int index) const;
|
||||
|
||||
private:
|
||||
const char *line;
|
||||
size_t size;
|
||||
int argc;
|
||||
mutable int currentIndex;
|
||||
mutable size_t currentPosn;
|
||||
|
||||
// Disable copy constructor and operator=().
|
||||
ShellArguments(const ShellArguments &other) {}
|
||||
ShellArguments &operator=(const ShellArguments &) { return *this; }
|
||||
};
|
||||
|
||||
/** @cond */
|
||||
|
||||
inline ShellCommandRegister::ShellCommandRegister(const ShellCommandInfo *_info)
|
||||
: info(_info)
|
||||
, next(0)
|
||||
{
|
||||
Shell::registerCommand(this);
|
||||
}
|
||||
|
||||
/** @endcond */
|
||||
|
||||
#define ShellCommand(name,help,function) \
|
||||
static char const shell_id_##name[] PROGMEM = #name; \
|
||||
static char const shell_help_##name[] PROGMEM = help; \
|
||||
static ShellCommandInfo const shell_info_##name PROGMEM = { \
|
||||
shell_id_##name, \
|
||||
shell_help_##name, \
|
||||
(function) \
|
||||
}; \
|
||||
static ShellCommandRegister shell_cmd_##name(&shell_info_##name)
|
||||
|
||||
#endif
|
||||
116
libraries/Shell/TelnetDefs.h
Normal file
116
libraries/Shell/TelnetDefs.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Southern Storm Software, Pty Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef TELNET_DEFS_h
|
||||
#define TELNET_DEFS_h
|
||||
|
||||
// References:
|
||||
// https://tools.ietf.org/html/rfc854
|
||||
// http://www.iana.org/assignments/telnet-options/telnet-options.xhtml
|
||||
|
||||
namespace TelnetDefs
|
||||
{
|
||||
|
||||
/** Telnet commands */
|
||||
enum Command
|
||||
{
|
||||
EndOfFile = 236, /**< EOF */
|
||||
Suspend = 237, /**< Suspend process */
|
||||
Abort = 238, /**< Abort process */
|
||||
EndOfRecord = 239, /**< End of record command */
|
||||
SubEnd = 240, /**< End option sub-negotiation */
|
||||
NOP = 241, /**< No operation */
|
||||
DataMark = 242, /**< Data mark */
|
||||
Break = 243, /**< Break */
|
||||
Interrupt = 244, /**< Interrupt process */
|
||||
AbortOutput = 245, /**< Abort output */
|
||||
AreYouThere = 246, /**< Are you there? */
|
||||
EraseChar = 247, /**< Erase character */
|
||||
EraseLine = 248, /**< Erase line */
|
||||
GoAhead = 249, /**< Go ahead in half-duplex mode */
|
||||
SubStart = 250, /**< Option sub-negotiation */
|
||||
WILL = 251, /**< Will use option */
|
||||
WONT = 252, /**< Won't use option */
|
||||
DO = 253, /**< Do use option */
|
||||
DONT = 254, /**< Don't use option */
|
||||
IAC = 255 /**< Interpret As Command */
|
||||
};
|
||||
|
||||
/** Telnet options used in sub-negotiations */
|
||||
enum Option
|
||||
{
|
||||
Binary = 0, /**< Binary transmission */
|
||||
Echo = 1, /**< Echo */
|
||||
Reconnection = 2, /**< Reconnection */
|
||||
SuppressGoAhead = 3, /**< Suppress half-duplex go ahead signals */
|
||||
ApproxMsgSize = 4, /**< Approx message size negotiation */
|
||||
Status = 5, /**< Give status on prevailing options */
|
||||
TimingMark = 6, /**< Timing mark */
|
||||
RemoteTransmitEcho = 7, /**< Remote controlled transmit and echo */
|
||||
LineWidth = 8, /**< Line width */
|
||||
PageSize = 9, /**< Page size */
|
||||
CarriageReturn = 10, /**< Carriage return disposition */
|
||||
HorzTabStops = 11, /**< Horizontal tab stops */
|
||||
HorzTabStopDisp = 12, /**< Horizontal tab stop disposition */
|
||||
FormFeed = 13, /**< Form feed disposition */
|
||||
VertTabStops = 14, /**< Vertical tab stops */
|
||||
VertTabStopDisp = 15, /**< Vertical tab stop disposition */
|
||||
LineFeed = 16, /**< Line feed disposition */
|
||||
ExtendedASCII = 17, /**< Extended ASCII */
|
||||
Logout = 18, /**< Force logout */
|
||||
ByteMacro = 19, /**< Byte macro */
|
||||
DataEntryTerminal = 20, /**< Data entry terminal */
|
||||
SUPDUP = 21, /**< SUPDUP protocol */
|
||||
SUPDUPOutput = 22, /**< SUPDUP output */
|
||||
SendLocation = 23, /**< Send the user's location */
|
||||
TerminalType = 24, /**< Terminal type */
|
||||
EndOfRecordOption = 25, /**< End of record option */
|
||||
TACACSUserId = 26, /**< TACACS user identification */
|
||||
OutputMarking = 27, /**< Output marking */
|
||||
TerminalLocation = 28, /**< Terminal location number */
|
||||
Telnet3270Regime = 29, /**< Telnet 3270 regime */
|
||||
X3Pad = 30, /**< X.3 PAD */
|
||||
WindowSize = 31, /**< Window size */
|
||||
Speed = 32, /**< Terminal speed */
|
||||
RemoteFlowControl = 33, /**< Remote flow control */
|
||||
Linemode = 34, /**< Linemode option */
|
||||
XDisplay = 35, /**< X display location */
|
||||
EnvironmentOld = 36, /**< Environment variables (old version) */
|
||||
Authentication = 37, /**< Authentication */
|
||||
Encryption = 38, /**< Encryption */
|
||||
Environment = 39, /**< Environment variables (new version) */
|
||||
TN3270E = 40, /**< TN3270E */
|
||||
XAUTH = 41, /**< XAUTH */
|
||||
Charset = 42, /**< Character set */
|
||||
RemoteSerialPort = 43, /**< Remote serial port */
|
||||
ComPortControl = 44, /**< COM port control */
|
||||
SuppressLocalEcho = 45, /**< Suppress local echo */
|
||||
StartTLS = 46, /**< Start TLS session */
|
||||
Kermit = 47, /**< KERMIT protocol */
|
||||
SendURL = 48, /**< Send URL */
|
||||
ForwardX = 49, /**< Forward X protocol */
|
||||
Extended = 255 /**< Extended options list */
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
1464
libraries/Shell/Terminal.cpp
Normal file
1464
libraries/Shell/Terminal.cpp
Normal file
File diff suppressed because it is too large
Load Diff
146
libraries/Shell/Terminal.h
Normal file
146
libraries/Shell/Terminal.h
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Southern Storm Software, Pty Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef TERMINAL_h
|
||||
#define TERMINAL_h
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <USBAPI.h>
|
||||
#include "USBKeysExtra.h"
|
||||
|
||||
// Special key code that indicates that unicodeKey() contains the actual code.
|
||||
#define KEY_UNICODE 0x1000
|
||||
|
||||
// Special key code that indicates that the window size has changed.
|
||||
#define KEY_WINSIZE 0x1001
|
||||
|
||||
class Terminal : public Stream
|
||||
{
|
||||
public:
|
||||
Terminal();
|
||||
virtual ~Terminal();
|
||||
|
||||
enum Mode
|
||||
{
|
||||
Serial,
|
||||
Telnet
|
||||
};
|
||||
|
||||
void begin(Stream &stream, Mode mode = Serial);
|
||||
void end();
|
||||
|
||||
Stream *stream() const { return _stream; }
|
||||
Terminal::Mode mode() const { return (Terminal::Mode)mod; }
|
||||
|
||||
virtual int available();
|
||||
virtual int peek();
|
||||
virtual int read();
|
||||
|
||||
virtual void flush();
|
||||
|
||||
virtual size_t write(uint8_t c);
|
||||
virtual size_t write(const uint8_t *buffer, size_t size);
|
||||
using Stream::write;
|
||||
|
||||
void writeProgMem(const char *str);
|
||||
|
||||
int readKey();
|
||||
|
||||
long unicodeKey() const { return ucode; }
|
||||
|
||||
size_t writeUnicode(long code);
|
||||
|
||||
int columns() const { return ncols; }
|
||||
int rows() const { return nrows; }
|
||||
|
||||
bool setWindowSize(int columns, int rows);
|
||||
|
||||
void clear();
|
||||
void clearToEOL();
|
||||
|
||||
void cursorMove(int x, int y);
|
||||
void cursorLeft();
|
||||
void cursorRight();
|
||||
void cursorUp();
|
||||
void cursorDown();
|
||||
|
||||
void backspace();
|
||||
|
||||
void insertLine();
|
||||
void insertChar();
|
||||
void deleteLine();
|
||||
void deleteChar();
|
||||
|
||||
void scrollUp();
|
||||
void scrollDown();
|
||||
|
||||
void normal();
|
||||
void bold();
|
||||
void underline();
|
||||
void blink();
|
||||
void reverse();
|
||||
|
||||
enum Color
|
||||
{
|
||||
Black = 0x00,
|
||||
DarkRed = 0x01,
|
||||
DarkGreen = 0x02,
|
||||
DarkYellow = 0x03,
|
||||
DarkBlue = 0x04,
|
||||
DarkMagenta = 0x05,
|
||||
DarkCyan = 0x06,
|
||||
LightGray = 0x07,
|
||||
DarkGray = 0x08,
|
||||
Red = 0x09,
|
||||
Green = 0x0A,
|
||||
Yellow = 0x0B,
|
||||
Blue = 0x0C,
|
||||
Magenta = 0x0D,
|
||||
Cyan = 0x0E,
|
||||
White = 0x0F
|
||||
};
|
||||
|
||||
void color(Color fg);
|
||||
void color(Color fg, Color bg);
|
||||
|
||||
static bool isWideCharacter(long code);
|
||||
|
||||
static size_t utf8Length(long code);
|
||||
static size_t utf8Format(uint8_t *buffer, long code);
|
||||
|
||||
private:
|
||||
Stream *_stream;
|
||||
long ucode;
|
||||
int ncols, nrows;
|
||||
unsigned long timer;
|
||||
uint16_t offset;
|
||||
uint8_t state;
|
||||
uint8_t utf8len;
|
||||
uint8_t mod;
|
||||
uint8_t sb[8];
|
||||
uint8_t flags;
|
||||
|
||||
int matchEscape(int ch);
|
||||
void telnetCommand(uint8_t type, uint8_t option);
|
||||
};
|
||||
|
||||
#endif
|
||||
124
libraries/Shell/USBKeysExtra.h
Normal file
124
libraries/Shell/USBKeysExtra.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Southern Storm Software, Pty Ltd.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef USBKEYSEXTRA_h
|
||||
#define USBKEYSEXTRA_h
|
||||
|
||||
// Extra key codes that are not included in the standard USBAPI.h header.
|
||||
// Reference: http://www.usb.org/developers/hidpage/Hut1_12v2.pdf
|
||||
// Note: USBAPI.h shifts the Hut codes by adding 136 (0x88) so that
|
||||
// they don't intersect with ASCII. We do that here as well so
|
||||
// that these codes can be used with Keyboard.press(). We use #ifndef
|
||||
// here in case the core Arduino libraries add these in the future.
|
||||
|
||||
#ifndef KEY_PRINT_SCREEN
|
||||
#define KEY_PRINT_SCREEN (0x46 + 0x88)
|
||||
#endif
|
||||
#ifndef KEY_SCROLL_LOCK
|
||||
#define KEY_SCROLL_LOCK (0x47 + 0x88)
|
||||
#endif
|
||||
#ifndef KEY_PAUSE
|
||||
#define KEY_PAUSE (0x48 + 0x88)
|
||||
#endif
|
||||
#ifndef KEY_NUM_LOCK
|
||||
#define KEY_NUM_LOCK (0x53 + 0x88)
|
||||
#endif
|
||||
#ifndef KEY_NUMPAD_5
|
||||
#define KEY_NUMPAD_5 (0x5D + 0x88)
|
||||
#endif
|
||||
#ifndef KEY_F13
|
||||
#define KEY_F13 (0x68 + 0x88)
|
||||
#endif
|
||||
#ifndef KEY_F14
|
||||
#define KEY_F14 (0x69 + 0x88)
|
||||
#endif
|
||||
#ifndef KEY_F15
|
||||
#define KEY_F15 (0x6A + 0x88)
|
||||
#endif
|
||||
#ifndef KEY_F16
|
||||
#define KEY_F16 (0x6B + 0x88)
|
||||
#endif
|
||||
#ifndef KEY_F17
|
||||
#define KEY_F17 (0x6C + 0x88)
|
||||
#endif
|
||||
#ifndef KEY_F18
|
||||
#define KEY_F18 (0x6D + 0x88)
|
||||
#endif
|
||||
#ifndef KEY_F19
|
||||
#define KEY_F19 (0x6E + 0x88)
|
||||
#endif
|
||||
#ifndef KEY_F20
|
||||
#define KEY_F20 (0x6F + 0x88)
|
||||
#endif
|
||||
#ifndef KEY_F21
|
||||
#define KEY_F21 (0x70 + 0x88)
|
||||
#endif
|
||||
#ifndef KEY_F22
|
||||
#define KEY_F22 (0x71 + 0x88)
|
||||
#endif
|
||||
#ifndef KEY_F23
|
||||
#define KEY_F23 (0x72 + 0x88)
|
||||
#endif
|
||||
#ifndef KEY_F24
|
||||
#define KEY_F24 (0x73 + 0x88)
|
||||
#endif
|
||||
|
||||
// USB does not have a code for "Back Tab" as it is usually Shift-TAB.
|
||||
// For convenience, we map it to the ASCII vertical tab character (0x0B).
|
||||
#define KEY_BACK_TAB 0x0B
|
||||
|
||||
#ifndef KEY_RETURN
|
||||
|
||||
// If the Arduino variant does not support USB, then USBAPI.h will not
|
||||
// define the key codes that we need. So we define them here instead.
|
||||
|
||||
#define KEY_RETURN (0x28 + 0x88)
|
||||
#define KEY_ESC (0x29 + 0x88)
|
||||
#define KEY_BACKSPACE (0x2A + 0x88)
|
||||
#define KEY_TAB (0x2B + 0x88)
|
||||
#define KEY_CAPS_LOCK (0x39 + 0x88)
|
||||
#define KEY_F1 (0x3A + 0x88)
|
||||
#define KEY_F2 (0x3B + 0x88)
|
||||
#define KEY_F3 (0x3C + 0x88)
|
||||
#define KEY_F4 (0x3D + 0x88)
|
||||
#define KEY_F5 (0x3E + 0x88)
|
||||
#define KEY_F6 (0x3F + 0x88)
|
||||
#define KEY_F7 (0x40 + 0x88)
|
||||
#define KEY_F8 (0x41 + 0x88)
|
||||
#define KEY_F9 (0x42 + 0x88)
|
||||
#define KEY_F10 (0x43 + 0x88)
|
||||
#define KEY_F11 (0x44 + 0x88)
|
||||
#define KEY_F12 (0x45 + 0x88)
|
||||
#define KEY_INSERT (0x49 + 0x88)
|
||||
#define KEY_HOME (0x4A + 0x88)
|
||||
#define KEY_PAGE_UP (0x4B + 0x88)
|
||||
#define KEY_DELETE (0x4C + 0x88)
|
||||
#define KEY_END (0x4D + 0x88)
|
||||
#define KEY_PAGE_DOWN (0x4E + 0x88)
|
||||
#define KEY_RIGHT_ARROW (0x4F + 0x88)
|
||||
#define KEY_LEFT_ARROW (0x50 + 0x88)
|
||||
#define KEY_DOWN_ARROW (0x51 + 0x88)
|
||||
#define KEY_UP_ARROW (0x52 + 0x88)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
127
libraries/Shell/examples/Keys/Keys.ino
Normal file
127
libraries/Shell/examples/Keys/Keys.ino
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
This example tests the Terminal class by displaying the VT100 keys that
|
||||
are pressed. A real terminal program like PuTTY will be needed.
|
||||
|
||||
This example is placed into the public domain.
|
||||
*/
|
||||
|
||||
#include <Terminal.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
Terminal term;
|
||||
|
||||
#define K(name) {name, #name}
|
||||
struct KeyInfo
|
||||
{
|
||||
uint8_t code;
|
||||
char name[19];
|
||||
};
|
||||
struct KeyInfo const keys[] PROGMEM = {
|
||||
K(KEY_RETURN),
|
||||
K(KEY_ESC),
|
||||
K(KEY_BACKSPACE),
|
||||
K(KEY_TAB),
|
||||
K(KEY_BACK_TAB),
|
||||
K(KEY_CAPS_LOCK),
|
||||
K(KEY_F1),
|
||||
K(KEY_F2),
|
||||
K(KEY_F3),
|
||||
K(KEY_F4),
|
||||
K(KEY_F5),
|
||||
K(KEY_F6),
|
||||
K(KEY_F7),
|
||||
K(KEY_F8),
|
||||
K(KEY_F9),
|
||||
K(KEY_F10),
|
||||
K(KEY_F11),
|
||||
K(KEY_F12),
|
||||
K(KEY_F13),
|
||||
K(KEY_F14),
|
||||
K(KEY_F15),
|
||||
K(KEY_F16),
|
||||
K(KEY_F17),
|
||||
K(KEY_F18),
|
||||
K(KEY_F19),
|
||||
K(KEY_F20),
|
||||
K(KEY_F21),
|
||||
K(KEY_F22),
|
||||
K(KEY_F23),
|
||||
K(KEY_F24),
|
||||
K(KEY_INSERT),
|
||||
K(KEY_HOME),
|
||||
K(KEY_PAGE_UP),
|
||||
K(KEY_DELETE),
|
||||
K(KEY_END),
|
||||
K(KEY_PAGE_DOWN),
|
||||
K(KEY_RIGHT_ARROW),
|
||||
K(KEY_LEFT_ARROW),
|
||||
K(KEY_DOWN_ARROW),
|
||||
K(KEY_UP_ARROW),
|
||||
K(KEY_PRINT_SCREEN),
|
||||
K(KEY_SCROLL_LOCK),
|
||||
K(KEY_PAUSE),
|
||||
K(KEY_NUM_LOCK),
|
||||
K(KEY_NUMPAD_5),
|
||||
{0, ""}
|
||||
};
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
term.begin(Serial);
|
||||
|
||||
term.println("Press keys to see their codes ...");
|
||||
term.println();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
int key = term.readKey();
|
||||
if (key >= 0x21 && key <= 0x7E) {
|
||||
// Printable ASCII character.
|
||||
term.print("ASCII: ");
|
||||
term.write((uint8_t)key);
|
||||
term.println();
|
||||
} else if (key == 0x20) {
|
||||
// Space.
|
||||
term.println("ASCII: SPACE");
|
||||
} else if (key == KEY_UNICODE) {
|
||||
// Extended Unicode character.
|
||||
term.print("Unicode: U+");
|
||||
term.print(term.unicodeKey(), 16);
|
||||
term.println();
|
||||
} else if (key == KEY_WINSIZE) {
|
||||
// Change in window size.
|
||||
term.print("New window size: ");
|
||||
term.print(term.columns());
|
||||
term.print("x");
|
||||
term.println(term.rows());
|
||||
} else if (key >= 0 && key <= 0xFF) {
|
||||
// Special arrow or function key.
|
||||
const uint8_t *table = (const uint8_t *)keys;
|
||||
int code;
|
||||
while ((code = pgm_read_byte(table)) != 0) {
|
||||
if (code == key) {
|
||||
term.print("Special: ");
|
||||
term.writeProgMem((const char *)(table + 1));
|
||||
term.println();
|
||||
break;
|
||||
}
|
||||
table += sizeof(struct KeyInfo);
|
||||
}
|
||||
if (!code) {
|
||||
// Non-printable ASCII or unknown key.
|
||||
if (key < 0x20)
|
||||
term.print("ASCII: 0x");
|
||||
else
|
||||
term.print("Unknown: 0x");
|
||||
term.print(key, 16);
|
||||
term.println();
|
||||
}
|
||||
} else if (key >= 0) {
|
||||
// Unknown keycode. Print in hex.
|
||||
term.print("Unknown: 0x");
|
||||
term.print(key, 16);
|
||||
term.println();
|
||||
}
|
||||
}
|
||||
35
libraries/Shell/examples/SerialShell/SerialShell.ino
Normal file
35
libraries/Shell/examples/SerialShell/SerialShell.ino
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
This example demonstrates how to create a simple shell on the serial port.
|
||||
|
||||
This example is placed into the public domain.
|
||||
*/
|
||||
|
||||
#include <Shell.h>
|
||||
|
||||
Shell shell;
|
||||
|
||||
int ledPin = 13;
|
||||
|
||||
void cmdLed(Shell &shell, int argc, const ShellArguments &argv)
|
||||
{
|
||||
if (argc > 1 && !strcmp(argv[1], "on"))
|
||||
digitalWrite(ledPin, HIGH);
|
||||
else
|
||||
digitalWrite(ledPin, LOW);
|
||||
}
|
||||
|
||||
ShellCommand(led, "Turns the status LED on or off", cmdLed);
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(ledPin, OUTPUT);
|
||||
|
||||
Serial.begin(9600);
|
||||
shell.setPrompt("Command: ");
|
||||
shell.begin(Serial, 5);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
shell.loop();
|
||||
}
|
||||
80
libraries/Shell/examples/TelnetServer/TelnetServer.ino
Normal file
80
libraries/Shell/examples/TelnetServer/TelnetServer.ino
Normal file
@@ -0,0 +1,80 @@
|
||||
|
||||
/*
|
||||
This example demonstrates how to create a simple telnet server.
|
||||
|
||||
This example is placed into the public domain.
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <Ethernet.h>
|
||||
#include <Shell.h>
|
||||
#include <LoginShell.h>
|
||||
|
||||
byte macAddress[6] = {
|
||||
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
|
||||
};
|
||||
|
||||
int ledPin = 13;
|
||||
|
||||
EthernetServer server(23);
|
||||
EthernetClient client;
|
||||
bool haveClient = false;
|
||||
|
||||
LoginShell shell;
|
||||
|
||||
void cmdLed(Shell &shell, int argc, const ShellArguments &argv)
|
||||
{
|
||||
if (argc > 1 && !strcmp(argv[1], "on"))
|
||||
digitalWrite(ledPin, HIGH);
|
||||
else
|
||||
digitalWrite(ledPin, LOW);
|
||||
}
|
||||
|
||||
ShellCommand(led, "Turns the status LED on or off", cmdLed);
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Configure I/O.
|
||||
pinMode(ledPin, OUTPUT);
|
||||
digitalWrite(ledPin, LOW);
|
||||
|
||||
// Start the serial port for status messages.
|
||||
Serial.begin(9600);
|
||||
Serial.println();
|
||||
Serial.print("Acquiring IP address ... ");
|
||||
|
||||
// Start Ethernet running and get an IP address via DHCP.
|
||||
if (Ethernet.begin(macAddress))
|
||||
Serial.println(Ethernet.localIP());
|
||||
else
|
||||
Serial.println("failed");
|
||||
|
||||
// Listen on port 23 for incoming telnet connections.
|
||||
server.begin();
|
||||
shell.setMachineName("Arduino");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Maintain the DHCP lease over time.
|
||||
Ethernet.maintain();
|
||||
|
||||
// Handle new/disconnecting clients.
|
||||
if (!haveClient) {
|
||||
// Check for new client connections.
|
||||
client = server.available();
|
||||
if (client) {
|
||||
haveClient = true;
|
||||
shell.begin(client, 5);
|
||||
}
|
||||
} else if (!client.connected()) {
|
||||
// The current client has been disconnected. Shut down the shell.
|
||||
shell.end();
|
||||
client.stop();
|
||||
client = EthernetClient();
|
||||
haveClient = false;
|
||||
}
|
||||
|
||||
// Perform periodic shell processing on the active client.
|
||||
shell.loop();
|
||||
}
|
||||
4
libraries/Shell/keywords.txt
Normal file
4
libraries/Shell/keywords.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
Shell KEYWORD1
|
||||
LoginShell KEYWORD1
|
||||
Terminal KEYWORD1
|
||||
loop KEYWORD2
|
||||
Reference in New Issue
Block a user