Difference between revisions of "Development/ECMD"

From Ethersex_Wiki
Jump to: navigation, search
(first version)
 
(Parameters)
 
Line 31: Line 31:
 
== Parameters ==
 
== Parameters ==
  
* *cmd holds '''ARGUMENT1'''...'''ARGUMENTN'''  which have been passed along with the command
+
* *cmd holds '''ARGUMENT1'''...'''ARGUMENTN'''  which have been passed along with the command. The command text you specified with ecmd_feature macro has already been stripped off, *cmd points to the arguments only. The length of the commandbuffer varies, and may not be zero-terminated properly.
* len is the length of the command (*cmd). Use this for securely parsing *cmd.
+
* <strike>len is the length of the command (*cmd). Use this for securely parsing *cmd.</strike> len is the length of the output buffer. Do NOT write beyond this limit. Always check the remaining buffersize, or use snprintf_P with proper len param2. The output buffersize depends on the module that called the parser routine: UDP uses the remainder of the UIP buffer (first part of uip_buf holds the command), which is quite large. I2C uses ECMD_I2C_BUFFER_LEN, U(S)ART uses ECMD_SERIAL_USART_BUFFER_LEN and TCP uses ECMD_INPUTBUF_LENGTH (which is wrong, should be ECMD_OUTPUTBUF_LENGTH but both are equal and only 50 chars by default). If you have more text, use the ECMD_AGAIN return value: your routine will get called again in the next cycle. If your text should be continued on the same line, TCP has an ECMD_NO_NEWLINE mechanism at least for the first call, but other channels have not.  
* *output is the output buffer which can hold 50 bytes/characters
+
* *output is the output buffer <strike>which can hold 50 bytes/characters</strike>
  
 
== Return values ==
 
== Return values ==

Latest revision as of 04:33, 26 July 2012

For general information on ECMD, see ECMD.

The following variables will be used on this page. Replace them for your module.

  • COMMAND - how the command will be invoked
  • ARGUMENT1...ARGUMENTN - the arguments that will be passed together with COMMAND
  • FUNCTIONNAME - the name of the function which will handle the command
  • MODULENAME - the name of the module

Preparations

  • Create a new file inside the folder of the module MODULENAME_ecmd.c
  • Add this file to the Makefile of the module.
  • Open the file and "#include "protocols/ecmd/ecmd-base.h" and other necessary headers.
  • Add the header of the module, <string.h> etc.

Create a new command

Start with the following template:

int16_t parse_cmd_FUNCTIONNAME (char *cmd, char *output, uint16_t len)
{
        /* Your Code here */
	return ECMD_FINAL_OK;
}

Whenever COMMAND is invoked, this function will be called to handle it.

Parameters

  • *cmd holds ARGUMENT1...ARGUMENTN which have been passed along with the command. The command text you specified with ecmd_feature macro has already been stripped off, *cmd points to the arguments only. The length of the commandbuffer varies, and may not be zero-terminated properly.
  • len is the length of the command (*cmd). Use this for securely parsing *cmd. len is the length of the output buffer. Do NOT write beyond this limit. Always check the remaining buffersize, or use snprintf_P with proper len param2. The output buffersize depends on the module that called the parser routine: UDP uses the remainder of the UIP buffer (first part of uip_buf holds the command), which is quite large. I2C uses ECMD_I2C_BUFFER_LEN, U(S)ART uses ECMD_SERIAL_USART_BUFFER_LEN and TCP uses ECMD_INPUTBUF_LENGTH (which is wrong, should be ECMD_OUTPUTBUF_LENGTH but both are equal and only 50 chars by default). If you have more text, use the ECMD_AGAIN return value: your routine will get called again in the next cycle. If your text should be continued on the same line, TCP has an ECMD_NO_NEWLINE mechanism at least for the first call, but other channels have not.
  • *output is the output buffer which can hold 50 bytes/characters

Return values

ECMD_FINAL_OK the command has been executed without any errors. "OK" will be written to the caller's output.
ECMD_FINAL(len) the command has been executed. len bytes of *output will be written to the caller's output
ECMD_AGAIN(len) the command has been executed but needs to be called again. len bytes of *output will be written to the caller's output
ECMD_ERR_PARSE_ERROR the command couldn't be executed (missing/wrong arguments etc.)
ECMD_ERR_READ_ERROR the command couldn't be executed (not able to read from device/hardware)
ECMD_ERR_WRITE_ERROR the command couldn't be executed (not able to write to device/hardware)

Announce the command

Append this to the bottom of MODULENAME_ecmd.c to let the ECMD parser know about the new command.

/*
-- Ethersex META --
block(MODULENAME)
ecmd_feature(FUNCTIONNAME, "COMMAND", ARGUMENT1...ARGUMENTN , DESCRIPTION)
*/

The COMMAND along with the arguments and the description will show up here

Tips and best practice

Recursive calling a command handler function

If you need to output a lot of data (>50 bytes) , you need to recursivly call the command handler function using ECMD_AGAIN().

Instead of using unsafe static variables to keep track of the current progress you can use the following code:

 /* trick: use bytes on cmd as "connection specific static variables" */
    if (cmd[0] != 23) {		/* indicator flag: real invocation:  0 */
	cmd[0] = 23;		/*                 continuing call: 23 */
	cmd[1] = 0;		/* local variable 1 */
    }

source example