> ## 11. General Purpose Console

> ### 11.1 Introduction

> The library, `zconsole.lib,` implements a serial-based console that can:

> - Configure a board.
> - Upload and download web pages.
> - Change web page variables without re-uploading the page.
> - Send e-mail.

> ### 11.2 Console Features

> Recognizing that embedded control systems are wide-ranging in their requirements, zconsole.lib was designed with flexibility and extensibility in mind. Designers can choose the available functionality they want and leave the rest alone. The Console includes:

> - Login name and password protection.
> - Default and custom Console commands.
> - Default and custom error messages.
> - Help text for Console commands, including custom commands
> - Multiple I/O streams that can be used simultaneously.
> - A fail-safe backup system for configuration data.

> #### 11.2.1 Using other Dynamic C Libraries

> An application program that uses the Console must include the lines

>     #use "filesystem.lib" // if using the improved file system
>                           // that is available starting with
>                           // Dynamic C 7.05, substitute "fs2.lib"
>                           // for "filesystem.lib"
>     #use "zconsole.lib"

> Dynamic C TCP/IP functionality may be used by a Console application program by including the appropriate libraries.

> ### 11.3 Login Name and Password

> There is a sample program, `/samples/tcpip/LOGINCONSOLE.C``,` that demonstrates the use of the login name/password functionality for the Console. The console command functions: `con_loginname()`, `con_loginpassword()` and `con_logout()` are described in Section 11.4.3.1 starting on page 272. The structure that saves the name and password information can be backed up using the backup macro `CONSOLE_BACKUP_LOGIN``.` Please see Section 11.7 starting on page 290 for details on the backup system.

> ### 11.4 Console Commands and Messages

> The Console is a command-driven application. A command is issued either at the keyboard using a terminal emulator or a command is generated and sent from an attached machine. The Console carries out the command, and either the message "OK" \r\n is returned, or an error is returned in the form of:

> ERROR XXXX This is an error message.\r\n

> Note that the carriage return and new line characters (\r\n) are always returned by the Console whether the command completed successfully or not.

> #### 11.4.1 Console Command Data Structure

> The command system is set up at compile time with an array of `ConsoleCommand` structures. There is one array entry for each command recognized by the Console.

>     typedef struct {
>        char* command;
>        int (*cmdfunc)();
>        long helptext;
>     } ConsoleCommand

> #### command

> This field is a string like the following: "SET MAIL FROM." That is, each word of the command is separated by a space. The case of the command does not matter. Entering this string is how the command is invoked.

> #### cmdfunc

> This field is a function pointer to the function that implements the command. The functions that come with the Console are listed in Section 11.4.3.1 on page 272.

> #### helptext

> This field points to a text file. The text file contains help information for the associated command. When `HELP` `COMMAND` is entered, this text file (the help information for `COMMAND`) will be printed to the Console. The help text comes from `#ximport`ed text files.

> #### 11.4.1.1 Help Text for General Cases

> There are two cases in `Zconsole.lib` where help text is needed, but is not associated with a particular command. It is still necessary to allocate a `ConsoleCommand` structure to access the help text. The first case is the help overview given when `HELP` is entered by itself. The `command` field should be "" and the `cmdfunc` field should be `NULL`.

>     { "", NULL, help_txt },

> The second case is `HELP` `SET`. This is an overview of the family of SET commands, i.e. commands that set configuration values. For `HELP` `SET`, the `command` field should be "SET" and the `cmdfunc` field should be `NULL`.

>     { "SET", NULL, help_set_txt },

> This second case illustrates the general case of displaying help for a family of commands. The family name can not be the name of a command.

> #### 11.4.2 Console Command Array

> An array of `ConsoleCommand` structures must be defined in an application program as a constant global variable named `console_commands[]`. All commands available at the Console, those provided in `Zconsole.lib` and custom commands, must have an entry in this array.

> #### 11.4.3 Console Commands

> The following is a list of the commands provided by `Zconsole.lib`. When the command name {i.e., the string in the `command` field) is received by the Console, the function pointed to in the `cmdfunc` field is executed. When the Console receives the command, `HELP` <command name>, the text file located at physical address `helptext` will be displayed.

>     const ConsoleCommand console_commands[] =
>     {
>        { "HELLO WORLD", hello_world, 0 },
>        { "ECHO", con_echo, help_echo_txt },
>        { "HELP", con_help, help_help_txt },
>        { "", NULL, help_txt },
>        { "SET", NULL, help_set_txt },
>        { "SET PARAM", con_set_param, 0 },
>        { "SET IP", con_set_ip, help_set_txt },
>        { "SET NETMASK", con_set_netmask, help_set_txt },
>        { "SET GATEWAY", con_set_gateway, help_set_txt },
>        { "SET NAMESERVER", con_set_nameserver, help_set_txt },
>        { "SET MAIL", NULL, help_set_mail_txt },
>        { "SET MAIL SERVER", con_set_mail_server, help_set_mail_server_txt },
>        { "SET MAIL FROM", con_set_mail_from, help_set_mail_from_txt },
>        { "SHOW", con_show, help_show_txt },
>        { "PUT", con_put, help_put_txt },
>        { "GET", con_get, help_get_txt },
>        { "DELETE", con_delete, help_delete_txt },
>        { "LIST", NULL, help_list_txt },
>        { "LIST FILES", con_list_files, help_list_txt },
>        { "LIST VARIABLES", con_list_variables, help_list_txt },
>        { "CREATEV", con_createv, help_createv_txt },
>        { "PUTV", con_putv, help_putv_txt },
>        { "GETV", con_getv, help_getv_txt },
>        { "MAIL", con_mail, help_mail_txt },
>        { "RESET FILES", con_reset_files, 0 }
>        { "RESET VARIABLES", con_reset_variables, help_reset_variables }
>     };

> #### 11.4.3.1 Default Command Functions

> The following functions are provided in `Zconsole.lib`. Each one takes a pointer to a `ConsoleState` structure as its only parameter, following the prototype for custom functions described in Section 11.4.3.2 on page 277. Each of these functions return `0` when it has more processing to do (and thus will be called again), `1` for successful completion of its task, and `-1` to report an error.

> Parameters needed by the commands using these functions are passed on the command line.

> ### con_createv()

> This function creates a variable that can be used with SSI commands in SHTML files. Certain SSI commands can be replaced by the value of this variable, so that a web page can be dynamically altered without re-uploading the entire page. Note, however, that the value of the variable is not preserved across power cycles, although the variable entry is still preserved. That is, the value of the variable may change after a power cycle. It can be changed again, though, with a `putv` command. It works in the following fashion (if the command is called "CREATEV"):

>     usage: "createv <varname> <vartype> <format> <value> [strlen]"

> A web variable that can be referenced within web files is created.

> `<varname>` is the name of the variable

> `<vartype>` is the type of the variable (`INT8`, `INT16`, `INT32`, `FLOAT32`, or `STRING`)

> `<format>` is the printf-style format specifier for outputting the variable (such as "%d")

> `<value>` is the value to assign the variable.

> `[strlen]` is only used if the variable is of type `STRING`. It is used to give the maximum length of the string.

> ### con_delete()

> This function deletes a file from the file system. A command that uses this function takes one parameter: the name of the file to delete.

> ### con_echo()

> This function turns on or off the echoing of characters on a particular I/O stream. That is, it does not affect echoing globally, but only for the I/O stream on which it is issued. A command that uses this function takes one parameter: `ON | OFF`.

> ### con_get()

> This function displays a file from the file system. It works in the following fashion (if the command is called "GET"):

> - ASCII mode: usage: "get <filename>"
>   The file is then sent, followed by the usual OK message.
> - BINARY mode: usage: "get <filename> <size in bytes>"
>   The message "LENGTH <len>" will be sent, indicating length of the file to be sent, and then the file will be sent, but not more than <size in bytes> bytes.

> ### con_getv()

> This function displays the value of the given variable. The variable is displayed using the printf-style format specifier given in the `createv` command. A command that uses this function takes one parameter: the name of the variable.

> ### con_help()

> This function implements the help system for the Console. A command that uses this function takes one parameter: the name of another command. The Console outputs the associated help text for the requested command. The help text is the text file referenced in the third field of the `ConsoleCommand` structure.

> ### con_list_files()

> This function lists the files in the file system and their file sizes. A command that uses this function takes no parameters.

> ### con_list_variables()

> This function displays the names and types of all variables. A command that uses this function takes no parameters.

> ### con_loginname()

> This function stores an identifier that will be remembered across power cycles (with battery-backed RAM). The existence of the identifier will be used to prompt the user of a new Console session. Before Console access to the controller is allowed, a valid identifier must be entered in response to the prompt. A command that uses this function takes one parameter: an identifier that will be used as the login name.

> ### con_loginpassword()

> This function stores an identifier that will be remembered across power cycles (with battery-backed RAM). The existence of the identifier will be used to prompt the user for a password after a login name has been entered. Before Console access to the controller is allowed, a valid identifier must be entered in response to the prompt. A command that uses this function takes no parameters on the command line, but requires a series of user inputs in response to prompts. In the following screen shot, the command is named "login password," and is typed in by the user. All other screen text shown here was printed by the Console.

> If no identifier is stored for the password, a `<CR>` must be sent in response to the prompt for the old password.

> NOTE | A login name must be stored by a command using `con_loginname()`for a login password to be applicable, i.e. if a password has been stored but no login name, new Console sessions will not prompt for the password or a login name. If a login name is applicable, but there is no password, new Console sessions will prompt for the login name and grant access after a valid name is entered without prompting for a password.

> ### con_logout()

> This function exits the current Console session and begins a new session by entering the initialization state of the Console. A command that uses this function takes no parameters.

> ### con_mail()

> This function sends e-mail to the server specified by `con_mail_server()`, with the return address specified by `set_mail_from()`. A command that uses this function takes one parameter: the destination e-mail address. If the command is named mail, the usage is:

>      "mail destination@where.com"

> The first line of the message will be used as the subject, and the other lines are the body. The body is terminated with a ^D or ^Z (0x04 or 0x1A).

> ### con_put()

> This function creates a new file in the file system for use with the HTTP server. It works in the following fashion (if the command is called "PUT"):

> - ASCII mode: usage: "put <filename>"
>   The file is then sent, terminating with a ^D or ^Z (0x04 or 0x1A).
> - BINARY mode: usage: "put <filename> <size in bytes>"
>   The file is then sent, and must be exactly the specified number of bytes in length.

> Note that ASCII mode is only useful for text files, since the Console will ignore non-displayable characters. In binary mode, the put command will time out after `CON_TIMEOUT` seconds of inactivity (60 by default).

> ### con_putv()

> This function updates the value of a variable. A command that uses this function takes two parameters: the name of the variable, and the new value for the variable.

> ### con_reset_files

> This function removes all web files.

> ### con_reset_variables

> This function removes all web variables.

> ### con_set_gateway()

> This function changes the gateway of the board. A command that uses this function takes one parameter: the new gateway in dotted quad notation, e.g., 192.168.1.1.

> ### con_set_ip()

> This function changes the IP address of the board. A command that uses this function takes one parameter: the new IP address in dotted quad notation, e.g., 192.168.1.112.

> ### con_set_param

> This function sets the parameter for the current I/O device. Depending on the I/O device, this value could be a baud rate, a port number or a channel number. A command that uses this function takes one parameter: the value for the I/O device parameter.

> ### con_set_mail_from

> This function sets the return address for all e-mail messages. This address will be added to the outgoing e-mail and should be valid in case the e-mail needs to be returned. A command that uses this function takes one parameter: the return address.

> ### con_set_mail_server

> This functions identifies the SMTP server to use. A command that uses this function takes one parameter: the IP address of the SMTP server.

> ### con_set_nameserver()

> This function changes the name server for the board. A command that uses this function takes one parameter: the IP address of the new name server in dotted quad notation, e.g., 192.168.1.1.

> ### con_set_netmask()

> This function changes the netmask of the board. A command that uses this function takes one parameter: the new netmask in dotted quad notation, e.g., 255.255.255.0.

> ### con_show()

> This function displays the current configuration of the board (IP address, netmask, and gateway). If the developer's application has configuration options she would like to show other than the IP address, netmask, and gateway, she will probably want to implement her own version of the show command. The new show command can be modelled after `con_show()` in `ZConsole.lib`. A command that uses this function takes no parameters.

> #### 11.4.3.2 Custom Console Commands

> Developers are not limited to the default commands. A custom command is easy to add to the Console; simply create an entry for it in `console_commands[]`. The three fields of this entry were described in Section 11.4.1. The first field is the name of the command. The second field is the function that implements the command. This function must follow this prototype:

>     int function_name ( ConsoleState* state );

> The parameter passed to the function is a structure of type `ConsoleState`. Some of the fields in this structure must be manipulated by your custom command function, other fields are used by `Zconsole.lib` and must not be changed by the your program.

>     typedef struct {
>        int console_number;
>        ConsoleIO* conio;
>        int state;
>        int laststate;

>        char command[CON_CMD_SIZE];
>        char* cmdptr;
>        char buffer[CON_BUF_SIZE];   // Use for reading in data.
>        char* bufferend;             // Use for reading in data.

>        ConsoleCommand* cmdspec;
>        int sawcr;
>        int sawesc;
>        int echo;                    // Check if echo is enabled, or change it.
>        int substate;
>        unsigned int error;
>        int numparams;               // Read-only: check # of parms in command.
>        char cmddata[CON_CMD_DATA_SIZE];
>        FileNumber filenum;          // Use for file processing.
>        File file;                   // Use for file processing.
>        int spec;                    // Use for working with Zserver entities
>        long timeout;                // Use for extending the time out.
>     } ConsoleState;

> To accomplish its tasks, the function should use `state->substate` for its state machine (which will be initialized to zero before dispatching the command handler), and
> `state->command` to read out the command buffer (to get other parameters to the command, for instance). In case of error, the function should set `state->error` to the appropriate value. The buffer at `state->cmddata` is available for the command to preserve data across invocations of the command's state machine. The size of the buffer is adjustable via the `CON_CMD_DATA_SIZE` macro (set to 16 bytes by default). Generally this buffer area will be cast into a data structure appropriate for the given command state machine.

> `IMPORTANT`: The fields discussed in the previous paragraph and the fields that have comments in the structure definition are the only ones that an application program should change. The other fields must not be changed.

> The function should return 0 when it has more processing to do (and thus will be called again), 1 for successful completion of its task, and -1 to report an error.

> The third and final field of the `console_commands[]` entry is the physical address of the help text file for the custom command in question. This file must be `#ximport`ed, along with all of the default command function help files that are being used.

> #### 11.4.4 Console Error Messages

> The Console library provides a list of default error messages for the default Console commands. An application program must define an array for these error messages, as well as for any custom error messages that are desired. To include only the default error messages, the following array is sufficient:

>     const ConsoleError console_errors[] = {
>        CON_STANDARD_ERRORS // includes all default error messages
>     }

> #### 11.4.4.1 Default Error Messages

> These are the error codes for the default error messages and the text that will be displayed by the Console if the error occurs.

>     #define CON_ERR_TIMEOUT         1
>     #define CON_ERR_BADCOMMAND      2
>     #define CON_ERR_BADPARAMETER    3
>     #define CON_ERR_NAMETOOLONG     4
>     #define CON_ERR_DUPLICATE       5
>     #define CON_ERR_BADFILESIZE     6
>     #define CON_ERR_SAVINGFILE      7
>     #define CON_ERR_READINGFILE     8
>     #define CON_ERR_FILENOTFOUND    9
>     #define CON_ERR_MSGTOOLONG     10
>     #define CON_ERR_SMTPERROR      11
>     #define CON_ERR_BADPASSPHRASE  12
>     #define CON_ERR_CANCELRESET    13
>     #define CON_ERR_BADVARTYPE     14
>     #define CON_ERR_BADVARVALUE    15
>     #define CON_ERR_NOVARSPACE     16
>     #define CON_ERR_VARNOTFOUND    17
>     #define CON_ERR_STRINGTOOLONG  18
>     #define CON_ERR_NOTAFILE       19
>     #define CON_ERR_NOTAVAR        20
>     #define CON_ERR_COMMANDTOOLONG 21
>     #define CON_ERR_BADIPADDRESS   22

>     #define CON_STANDARD_ERRORS \
>        { CON_ERR_TIMEOUT,        "Timed out." },\
>        { CON_ERR_BADCOMMAND,     "Unknown command." },\
>        { CON_ERR_BADPARAMETER,   "Bad or missing parameter." },\
>        { CON_ERR_NAMETOOLONG,    "Filename too long." },\
>        { CON_ERR_DUPLICATE,      "Duplicate object found." },\
>        { CON_ERR_BADFILESIZE,    "Bad file size." },\
>        { CON_ERR_SAVINGFILE,     "Error saving file." },\
>        { CON_ERR_READINGFILE,    "Error reading file." },\
>        { CON_ERR_FILENOTFOUND,   "File not found." },\
>        { CON_ERR_MSGTOOLONG,     "Mail message too long." },\
>        { CON_ERR_SMTPERROR,      "SMTP server error." },\
>        { CON_ERR_BADPASSPHRASE,  "Passphrases do not match!" },\
>        { CON_ERR_CANCELRESET,    "Reset cancelled." },\
>        { CON_ERR_BADVARTYPE,     "Bad variable type." },\
>        { CON_ERR_BADVARVALUE,    "Bad variable value." },\
>        { CON_ERR_NOVARSPACE,     "Out of variable space." },\
>        { CON_ERR_VARNOTFOUND,    "Variable not found." },\
>        { CON_ERR_STRINGTOOLONG,  "String too long." },\
>        { CON_ERR_NOTAFILE,       "Not a file." },\
>        { CON_ERR_NOTAVAR,        "Not a variable." },\
>        { CON_ERR_COMMANDTOOLONG, "Command too long." },\
>        { CON_ERR_BADIPADDRESS,   "Bad IP address."
>     }

> #### 11.4.4.2 Custom Error Messages

> Developers can create their own error messages by following the format of the default error messages. The error code numbers should be greater than 1,000 to save room for expansion of built-in error messages.

>     #define NEW_ERROR 1001

>     const ConsoleError console_errors[] = {
>        CON_STANDARD_ERRORS,     // includes all default error messages
>        { NEW_ERROR, "Any error message I want." }
>     }

> The default error messages should be included in `console_errors[]` along with any custom error messages that are used since the commands that come with `Zconsole.lib` each expect their own particular error message.

> ### 11.5 Console I/O Interface

> Multiple I/O methods are supported, as well as the ability to add custom I/O methods. An array of `ConsoleIO` structures must be defined in the application program and named `console_io[]`. This structure holds handlers for common I/O functions for the I/O method.

>     typedef struct {
>        long param;        // Baud for serial, port for telnet, etc.
>        int (*open) ();
>        void (*close)();
>        int (*tick) ();
>        int (*puts) ();
>        int (*rdUsed) ();
>        int (*wrUsed) ();
>        int (*wrFree) ();
>        int (*read) ();
>        int (*write) ();
>     } ConsoleIO;

> #### 11.5.1 How to Include an I/O Method

> Each supported I/O method is determined at compile time, i.e., each supported I/O method must have an entry in `console_io[]`.

> #### 11.5.2 Predefined I/O Methods

> Several predefined I/O methods are in `Zconsole.lib`. They will be included by entering their respective macros in `console_io[]`.

>     const ConsoleIO console_io[] = {
>        CONSOLE_IO_SERA(baud rate),
>        CONSOLE_IO_SERB(baud rate),
>        CONSOLE_IO_SERC(baud rate),
>        CONSOLE_IO_SERD(baud rate),
>        CONSOLE_IO_SP(channel number),
>        CONSOLE_IO_TELNET(port number),
>     }

> The macros expand to the appropriate set of pre-defined handler functions, e.g.,

>     #define CONSOLE_IO_SERA(param) { param, serAopen, serAclose, NULL, conio_serAputs, serArdUsed, serAwrUsed, serAwrFree, serAread, serAwrite}

> #### 11.5.2.1 Serial Ports

> There are predefined I/O methods for all four of the serial ports on a Rabbit board. The baud rate is set by passing it to the macro. See above.

> #### 11.5.2.2 Telnet

> The Console runs a telnet server. The port number is passed to the macro `CONSOLE_IO_TELNET`. The user telnets to the controller that is running the Console.

> #### 11.5.2.3 Slave Port

> The Rabbit slave port is an 8-bit bidirectional data port. The Console runs on the slave processor. Two drivers are needed.

> #### 11.5.2.3.1 Slave Port Driver

> The slave port driver is implemented by `SLAVE_PORT.LIB`. For an application to use the slave port:

> - The driver must be installed by including the library in the program.
> - A call to `SPinit(mode)` must be made to initialize the driver.
> - A function to process Console commands sent to the slave port must be provided.

> The slave port has 256 channels, separate port addresses that are independent of one another. A handler function for each channel that is used must be provided. For details on how to do this, please see the Dynamic C User's Manual.

> A stream-based handler, `SPShandler()`, to process Console commands for the slave is provided in `SP_STREAM.LIB`. The handler is set up automatically by the Console when the slave port I/O method is included. The macro, `CONSOLE_IO_SP`, expands to the I/O functions defined in `SP_STREAM.LIB`.

> #### 11.5.2.3.2 Master Connected to Rabbit Slave Port

> The master controller board can be another Rabbit processor or something else.

> The master also needs a driver for its end of the slave port connection. An example of the software needed on the master is given in `MASTER_SERIAL.LIB`. The software on the master controller is, of course, specific to the task at hand. In the example driver provided, most of the work is done by the slave, making minimal changes necessary to the code on the master.

> #### 11.5.2.4 Custom I/O Methods

> To define a custom I/O method, you must add a structure of type `ConsoleIO` to `console_io[]`. This structure holds the common handler functions for the I/O method. The tick function may have a `NULL` pointer, but the rest of the function pointers must be valid pointers to functions.

> #### 11.5.3 Multiple I/O Streams

> Each I/O method has its own state machine in the Console. That means that each I/O method is independent of the others and they can all be used simultaneously. This imposes the important restriction that all command handlers be able to run simultaneously on different I/O streams or support proper locking for functions that cannot be performed simultaneously.

> ### 11.6 Console Execution

> Normally, the Console will communicate over a serial link. The physical connection will differ slightly from board to board. Basically, you will need a 3 wire (GND, RXD, TXD) serial cable. In order to execute the Console several initialization steps must be taken at the beginning of an application program.

> #### 11.6.1 File System Initialization

> The Console depends on the file system that is included with Dynamic C. There are actually two file systems: FS1 was the first Dynamic C file system. The second one, FS2 (introduced with Dynamic C 7.05), is an improved file system.

> Besides defining the macro that directs the file system to EEPROM memory and including the appropriate library, i.e.,

>     #define FS_FLASH
>     #use "filesystem.lib" // If using the improved file system
>                           // that is available starting with
>                           // Dynamic C 7.05, substitute "fs2.lib"
>                           // for "filesystem.lib"

> the application program must initialize the file system with a call to `fs_init()`.

> #### 11.6.2 Serial Buffers

> If the pre-defined serial I/O methods are used, the circular buffers used for I/O data can be resized from their default values of 31 bytes by using macros. For example, if `CONSOLE_IO_SERIALC` is included in `console_io[]`, then lines similar to the following can be in the application program:

>     #define CINBUFSIZE 1023
>     #define COUTBUFSIZE 255

> In general, these buffers can be smaller for slower baud rates, but must be larger for faster baud rates.

> #### 11.6.3 Using TCP/IP

> To use the TCP/IP functionality of the Console you must have the following line in your application program:

>     #use "dcrtcp.lib"

> If you are serving web pages you must also include `http.lib`, and if you are sending e-mail you must include `smtp.lib`.

> #### 11.6.4 Required Console Functions

> To run the Console, the following two functions are required.

> ## console_init

>     int console_init(void);

> ### Description

> This function will initialize the Console data structures. It must be called before `console_tick()` is called for the first time. This function also loads the configuration information from the file system.

> ### Return value

> `0`: Success;
> `1`: No configuration information found.
> `<0:` Indicates an error loading the configuration data;
> `-1` indicates an error reading the 1st set of information,
> `-2` the 2nd set, and so on.

> ### Library

> zconsole.lib

> ## console_tick

>     void console_tick(void);

> ### Description

> This function needs to be called periodically in an application program to allow the Console time for processing.

> ### Library

> zconsole.lib

> #### 11.6.5 Useful Console Function

> Most of the following functions are only useful for creating custom commands.

> ## con_backup

>     int con_backup(void);

> ### Description

> This function backs up the current configuration.

> ### Return value

> `0`: Success
> `1`: Failure

> ### Library

> zconsole.lib

> ### See also

> con_backup_reserve, con_load_backup

> ## con_backup_bytes

>     long con_backup_bytes(void);

> ### Description

> Returns the number of bytes necessary for each backup configuration file. Note that enough space for 2 of these files needs to be reserved. This function is most useful when `ZCONSOLE.LIB` is being used with `FS2.LIB.`

> ### Return value

> Number of bytes needed for a backup configuration file.

> ### Library

> zconsole.lib

> ### See also

> con_backup_reserve

> ## con_backup_reserve

>     void con_backup_reserve(void);

> ### Description

> Reserves space for the configuration information in the file system. For more information on the file system see the Dynamic C User's Manual.

> ### Library

> zconsole.lib

> ### See also

> con_backup, con_load_backup, con_backup_bytes

> ## con_chk_timeout

>     int con_chk_timeout(unsigned long timeout);

> ### Description

> Checks whether the given timeout value has passed.

> ### Return value

> `0`: Timeout has not passed
> `!0`: Timeout has passed

> ### Library

> zconsole.lib

> ### See also

> con_set_timeout

> ## con_load_backup

>     int con_load_backup(void);

> ### Description

> Loads the configuration from the file system.

> ### Return value

> `0`: Success
> `1`: No configuration information found
> `<0`: Failure
> `-1`: error reading 1st set of information
> `-2:` error reading 2nd set of information, and so on

> ### Library

> zconsole.lib

> ### See also

> con_backup, con_backup_reserve

> ## con_reset_io

>     void con_reset_io(void);

> ### Description

> Resets all I/O methods by calling `close()` and `open()` on each of them.

> ### Library

> zconsole.lib

> ## con_set_backup_lx

>     void con_set_backup_lx(FSLXnum backuplx);

> ### Description

> Sets the logical extent (LX) that will be used to store the backup configuration data. For more information on the file system see the Dynamic C User's Manual. This is only useful in conjunction with `FS2.LIB`. This should be called once before `console_init()`. Care should be taken that enough space is available in this logical extent for the configuration files. See `con_backup_bytes()` for more information.

> ### Parameter

> #### backuplx

> LX number to use for backup

> ### Library

> zconsole.lib

> ### See also

> con_set_files_lx, con_backup_bytes

> ## con_set_files_lx

>     void con_set_files_lx(FSLXnum fileslx);

> ### Description

> Sets the logical extent (LX) that will be used to store files. For more information on the file system see the Dynamic C User's Manual. This is only useful in conjunction with `FS2.LIB`. This should be called once before `console_init()`.

> ### Parameter

> #### fileslx

> LX number to use for files.

> ### Library

> zconsole.lib

> ### See also

> con_set_backup_lx

> ## con_set_user_idle

>     void con_set_user_idle(void (*funcptr)());

> ### Description

> Sets a user-defined function that will be called when the console (for a particular I/O channel) is idle. The user-defined function should take an argument of type `ConsoleState*` .

> ### Library

> zconsole.lib

> ### See also

> con_set_user_timeout

> ## con_set_timeout

>     unsigned long con_set_timeout(unsigned int seconds);

> ### Description

> Returns the value that `MS_TIMER` should have when the number of seconds given have elapsed.

> ### Library

> zconsole.lib

> ### See also

> con_chk_timeout

> ## con_set_user_timeout

>     void con_set_user_timeout(void (*funcptr)());

> ### Description

> Sets a user-defined function that will be called when a timeout event has occurred. The user-defined function should take an argument of type `ConsoleState*`.

> ### Library

> zconsole.lib

> ### See also

> con_set_user_idle

> ## console_disable

>     void console_disable(int which);

> ### Description

> Disable processing for the designated console in the `console_io[]` array. This function, along with `console_enable()`, allows the sharing of the console port with some other processing.

> ### Parameter

> #### which

> The console to disable.

> ### Library

> zconsole.lib

> ### See Also

> console_init, console_enable

> ## console_enable

>     void console_enable(int which);

> ### Description

> Enable processing for the designated console in the `console_io[]` array. This function, along with `console_disable()`, allows the sharing of the console port with some other processing.

> ### Parameter

> #### which

> The console to enable.

> ### Library

> zconsole.lib

> ### See Also

> console_init, console_disable

> #### 11.6.6 Console Execution Choices

> The Console can be used interactively with a terminal emulator or by sending commands from a program running on a device connected to the controller that is running the Console.

> #### 11.6.6.1 Terminal Emulator

> To manually enter Console commands from a keyboard and view results in the Stdio window you must:

> 1. Run Dynamic C, version 7.05 or later.
> 2. Open a terminal emulator. Windows HyperTerminal comes with Windows. It does not work with binary files, only ASCII. Tera Term, available for free download at

>     http://hp.vector.co.jp/authors/VA002416/teraterm.html

> can handle both ASCII and binary.
> 1. Configure the terminal emulator as follows:
> COM port: (1 or 2) to which 3-wire serial cable is connected
> Baud Rate: 57,600 bps
> Data Bits: 8
> Parity: None
> Stop Bits: 1
> Flow Control: None

> The terminal emulator should now accept Console commands.

> To avoid losing a `<LF>` at the beginning of a file when using the `con_put` command function, select `Setup->Terminal` from the Tera Term menu and set the Transmit option to `CR+LF`. This option might be located elsewhere if you are using a different terminal emulator.

> ### 11.7 Backup System

> The Console can save configuration parameters to the file system so that they are available across power cycles. The backup process is done by `con_backup()`. Unlike the other console command functions, `con_backup()` does not take a parameter and it returns `0` if the backup was successful and `1` if it was not. This function is called by several of the console command functions that change configuration parameters, or that add or delete files or variables from the file system. Caution is advised when calling `con_backup()` since it writes to flash memory.

> #### 11.7.1 Data Structure for Backup System

> The developer must define an array called `console_backup[]` of `ConsoleBackup` structures.

>     typedef struct {
>        void* data;
>        int len;
>        void (*postload)();
>        void (*presave)();
>     } ConsoleBackup;

> #### data

> This is a pointer to the data to be backed up.

> #### len

> This is how many bytes of data need to be backed up.

> #### postload

> This is a function pointer to a function that is called after configuration data is loaded, in case the developer needs to do something with the newly loaded configuration data.

> #### presave

> This is a function pointer that is called just before the configuration data is saved so that the developer can fill in the data structure to be saved. The functions referenced by `postload()` and `presave()` should have the following prototype:

>     void my_preload(void* dataptr);

> The `dataptr` parameter is the address of the configuration data (the same as the data pointer in the `ConsoleBackup` structure).

> #### 11.7.2 Array Definition for Backup System

>     const ConsoleBackup console_backup[] = {
>        CONSOLE_BASIC_BACKUP,      // echo state, baud rate/port number
>        CONSOLE_TCPIP_BACKUP,
>        CONSOLE_HTTP_BACKUP,
>        CONSOLE_SMTP_BACKUP
>        CONSOLE_BACKUP_LOGIN
>        { my_data, my_data_len, my_preload, my_presave }
>     }

> `CONSOLE_BASIC_BACKUP` causes backup of the echo state (on or off), baud rate and port number information.

> `CONSOLE_TCPIP_BACKUP` causes backup of the IP addresses of the controller board and the IP address of its netmask, gateway and name server.

> `CONSOLE_HTTP_BACKUP` causes backup of the files and variables visible to the HTTP server.

> `CONSOLE_SMTP_BACKUP` causes backup of the mail configuration.

> `CONSOLE_BACKUP_LOGIN` causes backup of the `ConsoleLogin` structure which stores the login name and password strings.

> ### 11.8 Console Macros

> `Zconsole.lib` offers many macros that change the behavior of the Console.

> #### CON_BACKUP_FILE1

> The file number used for the first backup file. For FS1, this number must be in the range 128-143, so that `fs_reserve_blocks()` can be used to guarantee free space for the backup files. Defaults to 128 for FS1. Defaults to 254 for FS2.

> #### CON_BACKUP_FILE2

> Same as above, except this is for the second backup file. Two files are used so that configuration information is preserved even if the power cycles while configuration data is being saved. For FS1, this number must be in the range 128-143. Defaults to 129 for FS1. Defaults to 255 for FS2.

> #### CON_BUF_SIZE

> Changes the size of the data buffer that is allocated for each I/O method. If the baud rate or transfer speed is too great for the Console to keep up, then increasing this value may help avoid dropped characters. It is allocated in root data space. It defaults to 1024 bytes.

> #### CON_CMD_SIZE

> Changes the size of the command buffer that is allocated for each I/O method. This limits the length of a command line. It is allocated in root data space. Defaults to 128 bytes.

> #### CON_CMD_DATA_SIZE

> Default is 16. Adjusts the size of the user data area within the state structure so that user commands may preserve arbitrary information across calls. The user data area is allocated in root data space.

> #### CON_HELP_VERSION

> This macro should be defined if the developer wants a version message to be displayed when the HELP command is issued with no parameters. If this macro is defined, then the macro `CON_VERSION_MESSAGE` must also be defined.

> #### CON_INIT_MESSAGE

> Defines the message that is displayed on all Console I/O methods upon startup. Defaults to "Console Ready\r\n".

> #### CON_MAIL_BUF_SIZE

> Maximum length of a mail message. Defaults to 1024.

> #### CON_MAIL_FROM_SIZE

> Maximum length of mail from address to `NULL` terminator. Default to 51.

> #### CON_MAIL_SERV_SIZE

> Maximum length of mail server name and `NULL` terminator. Defaults to 51.

> #### CON_MAX_NAME

> Default is 10: maximum number of characters for a login name. This value must be equal to or less than `CON_CMD_DATA_SIZE`.

> #### CON_MAX_PASSWORD

> Default is 10: maximum number of characters for a login password.

> #### CON_SP_RDBUF_SIZE

> Size of the slave port read buffer. Defaults to 255.

> #### CON_SP_WRBUF_SIZE

> Size of the slave port write buffer. Defaults to 255.

> #### CON_TIMEOUT

> Adjusts the number of seconds that the Console will wait before cancelling the current command. The timeout can be adjusted in user code in the following manner:

>     state->timeout = con_set_timeout(CON_TIMEOUT);

> This is useful for custom user commands so that they can indicate when something "meaningful" has happened on the Console (such as some data being successfully transferred).

> #### CON_VAR_BUF_SIZE

> Adjusts the size of the variable buffer, in which values of variables can be stored for use with the HTTP server. It is allocated in xmem space. Defaults to 1024 bytes.

> #### CON_VERSION_MESSAGE

> This defines the version message to display when the HELP command is issued with no parameters. It is not defined by default, so has no default value.

> ### 11.9 Sample Program

>     /*****************************************************************
>     tcpipconsole.c
>     Z-World, 2001
>     This sample program demonstrates many of the features of zconsole.lib.

>     Among the features this sample program supports is network configuration, uploading web pages, changing variables for use with web pages, sending mail, and access to the console through a telnet client.
>     ********************************************************************/

>     #define MY_IP_ADDRESS  "10.10.6.112"
>     #define MY_NETMASK  "255.255.255.0"
>     #define MY_GATEWAY  "10.10.6.1"
>     #define MY_NAMESERVER  "10.10.6.1"
>     #define SMTP_SERVER  "10.10.6.1"

>     /*
>      * Size of the buffers for serial port C. If you want to use
>      * another serial port, you should change the buffer macros below
>      * appropriately (and change the console_io[] array below).
>      */
>     #define CINBUFSIZE  1023
>     #define COUTBUFSIZE  255

>     /*
>      * Maximum number of connections to the web server. This indicates
>      * the number of sockets that the web server will use.
>      */
>     #define HTTP_MAXSERVERS 2

>     /*
>      * Maximum number of sockets this program can use. The web server
>      * is taking two sockets (see above), the mail client uses one
>      * socket, and the telnet interface uses 1 socket.
>      */
>     #define MAX_SOCKETS 4

>     /*
>      * All web server content is dynamic, so we do not need
>      * http_flashspec[].
>      */
>     #define HTTP_NO_FLASHSPEC

>     /*
>      * The file system that the console uses should be located in flash.
>      */
>     #define FS_FLASH

>     /*
>      * Console configuration
>      */

>     /*
>      * The number of console I/O streams that this program supports. Since
>      * we are supporting serial port C and telnet, there are two I/O streams.
>      */
>     #define NUM_CONSOLES 2

>     /*
>      * If this macro is defined, then the version message will be shown
>      * with the help command (when the help command has no parameters).
>      */
>     #define CON_HELP_VERSION

>     /*
>      * Defines the version message that will be displayed in the help
>      * command if CON_HELP_VERSION is defined.
>      */
>     #define CON_VERSION_MESSAGE "TCP/IP Console Version 1.0\r\n"

>     /*
>      * Defines the message that is displayed on all I/O channels when the console starts.
>      */
>     #define CON_INIT_MESSAGE CON_VERSION_MESSAGE

>     /*
>      * These ximport directives include the help texts for the
>      * consolecommands. Having the help text in xmem helps save
>      * root code space.
>      */
>     #ximport "samples\zconsole\tcpipconsole_help\help.txt" help_txt

>     #ximport "samples\zconsole\tcpipconsole_help\help_help.txt" help_help_txt

>     #ximport "samples\zconsole\tcpipconsole_help\help_echo.txt" help_echo_txt

>     #ximport "samples\zconsole\tcpipconsole_help\help_set.txt" help_set_txt

>     #ximport "samples\zconsole\tcpipconsole_help\help_set_param.txt" help_set_param_txt

>     #ximport "samples\zconsole\tcpipconsole_help\help_set_mail.txt" help_set_mail_txt

>     #ximport "samples\zconsole\tcpipconsole_help\help_set_mail_server.txt" help_set_mail_server_txt

>     #ximport "samples\zconsole\tcpipconsole_help\help_set_mail_from.txt" help_set_mail_from_txt

>     #ximport "samples\zconsole\tcpipconsole_help\help_show.txt" help_show_txt

>     #ximport "samples\zconsole\tcpipconsole_help\help_put.txt" help_put_txt

>     #ximport "samples\zconsole\tcpipconsole_help\help_get.txt" help_get_txt

>     #ximport "samples\zconsole\tcpipconsole_help\help_delete.txt" help_delete_txt

>     #ximport "samples\zconsole\tcpipconsole_help\help_list.txt" help_list_txt

>     #ximport "samples\zconsole\tcpipconsole_help\help_createv.txt" help_createv_txt

>     #ximport "samples\zconsole\tcpipconsole_help\help_putv.txt" help_putv_txt

>     #ximport "samples\zconsole\tcpipconsole_help\help_getv.txt" help_getv_txt

>     #ximport "samples\zconsole\tcpipconsole_help\help_mail.txt" help_mail_txt

>     #ximport "samples\zconsole\tcpipconsole_help\help_reset.txt" help_reset_txt

>     #ximport "samples\zconsole\tcpipconsole_help\help_reset_files.txt" help_reset_files_txt

>     #ximport "samples\zconsole\tcpipconsole_help\help_reset_variables.txt"
>     help_reset_variables_txt

>     #memmap xmem

>     #use "FileSystem.lib"
>     #use "dcrtcp.lib"
>     #use "http.lib"
>     #use "smtp.lib"

>     /*
>      * Note that all libraries that zconsole.lib needs must be #use'd
>      * before #use'ing zconsole.lib .
>      */
>     #use "zconsole.lib"

>     /*
>      * This function prototype is for a custom command, so it must be
>      * declared before the console_command[] array.
>      */
>     int hello_world(ConsoleState* state);

>     /*
>      * This array defines which I/O streams for which the console will
>      * be available.  The streams included below are defined through
>      * macros. Available macros are CONSOLE_IO_SERA, CONSOLE_IO_SERB,
>      * CONSOLE_IO_SERC, CONSOLE_IO_SERD, CONSOLE_IO_TELNET, and
>      * CONSOLE_IO_SP (for the slave port). The parameter for the macro
>      * represents the initial baud rate for serial ports, the port
>      * number for telnet, or the channel number for the slave port.
>      * It is possible for the user to define her own I/O handlers and
>      * include them in a ConsoleIO structure in the console_io array.
>      * Remember that if you change the number of I/O streams here, you
>      * should also change the NUM_CONSOLES macro above.
>      */
>     const ConsoleIO console_io[] =
>     {
>        CONSOLE_IO_SERC(57600),
>        CONSOLE_IO_TELNET(23)
>     };

>     /*
>      * This array defines the commands that are available in the console.
>      * The first parameter for the ConsoleCommand structure is the
>      * command specification--that is, the means by which the console
>      * recognizes a command. The second parameter is the function
>      * to call when the command is recognized. The third parameter is
>      * the location of the #ximport'ed help file for the command.
>      * Note that the second parameter can be NULL, which is useful if
>      * help information is needed for something that is not a command
>      * (like for the "SET" command below--the help file for "SET"
>      * contains a list of all of the set commands). Also note the
>      * entry for the command "", which is used to set up the help text
>      * that is displayed when the help command is used by itself (that
>      * is, with no parameters).
>      */
>     const ConsoleCommand console_commands[] =
>     {
>        { "HELLO WORLD", hello_world, 0 },
>        { "ECHO", con_echo, help_echo_txt },
>        { "HELP", con_help, help_help_txt },
>        { "", NULL, help_txt },
>        { "SET", NULL, help_set_txt },
>        { "SET PARAM", con_set_param, help_set_param_txt },
>        { "SET IP", con_set_ip, help_set_txt },
>        { "SET NETMASK", con_set_netmask, help_set_txt },
>        { "SET GATEWAY", con_set_gateway, help_set_txt },
>        { "SET NAMESERVER", con_set_nameserver, help_set_txt },
>        { "SET MAIL", NULL, help_set_mail_txt },
>        { "SET MAIL SERVER", con_set_mail_server,
>              help_set_mail_server_txt },
>        { "SET MAIL FROM", con_set_mail_from, help_set_mail_from_txt },
>        { "SHOW", con_show, help_show_txt },
>        { "PUT", con_put, help_put_txt },
>        { "GET", con_get, help_get_txt },
>        { "DELETE", con_delete, help_delete_txt },
>        { "LIST", NULL, help_list_txt },
>        { "LIST FILES", con_list_files, help_list_txt },
>        { "LIST VARIABLES", con_list_variables, help_list_txt },
>        { "CREATEV", con_createv, help_createv_txt },
>        { "PUTV", con_putv, help_putv_txt },
>        { "GETV", con_getv, help_getv_txt },
>        { "MAIL", con_mail, help_mail_txt },
>        { "RESET", NULL, help_reset_txt },
>        { "RESET FILES", con_reset_files, help_reset_files_txt },
>        { "RESET VARIABLES", con_reset_variables,
>              help_reset_variables_txt }
>     };

>     /*
>      * This array sets up the error messages that can be generated.
>      * CON_STANDARD_ERRORS is a macro that expands to the standard
>      * errors that the built-in commands in zconsole.lib uses. Users
>      * can define their own errors here, as well.
>      */
>     const ConsoleError console_errors[] = {
>        CON_STANDARD_ERRORS
>     };
>     /*
>      * This array defines the information (such as configuration) that
>      * will be saved to the file system. Note that if, for example, the
>      * HTTP or SMTP related commands are include in the console_commands
>      * array above, then the backup information must be included in
>      * this array. The entries below are macros that expand to the
>      * appropriate entry for each set of functionality. Users can also
>      * add their own information to be backed up here by adding more
>      * ConsoleBackup structures.
>      */
>     const ConsoleBackup console_backup[] =
>     {
>        CONSOLE_BASIC_BACKUP,
>        CONSOLE_TCP_BACKUP,
>        CONSOLE_HTTP_BACKUP,
>        CONSOLE_SMTP_BACKUP
>     };

>     /*
>      * The following defines the MIME types that the web server will handle.
>      */
>     const HttpType http_types[] =
>     {
>        { ".shtml", "text/html", shtml_handler}, // ssi
>        { ".html", "text/html", NULL},           // html
>        { ".gif", "image/gif", NULL},
>        { ".jpg", "image/jpeg", NULL},
>        { ".jpeg", "image/jpeg", NULL},
>        { ".txt", "text/plain", NULL}
>     };

>     /*
>      * This is a custom command. Custom commands always take a
>      * ConsoleState* as an argument (a pointer to the state structure
>      * for the given I/O stream), and return an int. The return value
>      * should be 0 when the command wishes to be called again on the
>      * next console_tick(), 1 when the command has successfully
>      * finished processing, or -1 when the command has finished due
>      * to an error.
>      */
>     int hello_world(ConsoleState* state)
>     {
>        state->conio->puts("Hello, World!\r\n");
>        return 1;
>     }

>     void main(void)
>     {
>        /*
>         * All initialization of TCP/IP, clients, servers, and I/O
>         * must be done by the user prior to using any console functions.
>         */
>        sock_init();
>        tcp_reserveport(80);   // Enable SYN-queueing and disable the
>                                // 2MSL wait for the web server (results
>                                // in performance improvements).
>        http_init();

>        if (fs_init(0, 64)) {
>           printf("Filesystem not present!\n");
>        }

>        if (console_init() != 0) {
>           printf("Console did not initialize!\n");
>           fs_format(0, 64, 1);
>           /*
>            * Anytime after the file system has been initialized or
>            * formatted (after console_init() has been executed),
>            * con_backup_reserve() must be called to reserve space in
>            * the file system for the backup information.
>            */
>           con_backup_reserve();
>           con_backup();  // Save the backup information to the console.
>        }

>        while (1) {
>           console_tick();
>           http_handler();
>        }
>     }

Z-World http://www.zworld.com Voice: 530.757.3737 Fax: 530.757.3792 or 530.753.5141 sales@zworld.com