http://www.ethersex.de/index.php?title=Development/ECMD&feed=atom&action=historyDevelopment/ECMD - Revision history2024-03-29T06:07:35ZRevision history for this page on the wikiMediaWiki 1.30.0http://www.ethersex.de/index.php?title=Development/ECMD&diff=790&oldid=prevAtos: /* Parameters */2012-07-26T03:33:26Z<p><span dir="auto"><span class="autocomment">Parameters</span></span></p>
<table class="diff diff-contentalign-left" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr style="vertical-align: top;" lang="en">
<td colspan="2" style="background-color: white; color:black; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: white; color:black; text-align: center;">Revision as of 03:33, 26 July 2012</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l31" >Line 31:</td>
<td colspan="2" class="diff-lineno">Line 31:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>== Parameters ==</div></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>== Parameters ==</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'>−</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div>* *cmd holds '''ARGUMENT1'''...'''ARGUMENTN'''  which have been passed along with the command</div></td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>* *cmd holds '''ARGUMENT1'''...'''ARGUMENTN'''  which have been passed along with the command<ins class="diffchange diffchange-inline">. 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.</ins></div></td></tr>
<tr><td class='diff-marker'>−</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div>* len is the length of the command (*cmd). Use this for securely parsing *cmd.</div></td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>* <ins class="diffchange diffchange-inline"><strike></ins>len is the length of the command (*cmd). Use this for securely parsing *cmd<ins class="diffchange diffchange-inline">.</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</ins>.  </div></td></tr>
<tr><td class='diff-marker'>−</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div>* *output is the output buffer which can hold 50 bytes/characters</div></td><td class='diff-marker'>+</td><td style="color:black; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>* *output is the output buffer <ins class="diffchange diffchange-inline"><strike></ins>which can hold 50 bytes/characters<ins class="diffchange diffchange-inline"></strike></ins></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>== Return values ==</div></td><td class='diff-marker'> </td><td style="background-color: #f9f9f9; color: #333333; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #e6e6e6; vertical-align: top; white-space: pre-wrap;"><div>== Return values ==</div></td></tr>
</table>Atoshttp://www.ethersex.de/index.php?title=Development/ECMD&diff=410&oldid=prevMgue: first version2012-03-27T18:29:16Z<p>first version</p>
<p><b>New page</b></p><div>{{i18n|Development/ECMD}}<br />
For general information on ECMD, see [[ECMD]].<br />
<br />
The following variables will be used on this page. Replace them for your module.<br />
<br />
* '''COMMAND''' - how the command will be invoked<br />
* '''ARGUMENT1'''...'''ARGUMENTN''' - the arguments that will be passed together with '''COMMAND'''<br />
* '''FUNCTIONNAME''' - the name of the function which will handle the command<br />
* '''MODULENAME''' - the name of the module<br />
<br />
= Preparations =<br />
<br />
* Create a new file inside the folder of the module '''MODULENAME_ecmd.c'''<br />
* Add this file to the [[Development/Makefile | Makefile]] of the module.<br />
* Open the file and "#include "protocols/ecmd/ecmd-base.h" and other necessary headers.<br />
* Add the header of the module, <string.h> etc.<br />
<br />
= Create a new command =<br />
<br />
Start with the following template:<br />
<br />
<source lang="c"><br />
int16_t parse_cmd_FUNCTIONNAME (char *cmd, char *output, uint16_t len)<br />
{<br />
/* Your Code here */<br />
return ECMD_FINAL_OK;<br />
}<br />
</source><br />
Whenever '''COMMAND''' is invoked, this function will be called to handle it.<br />
<br />
== Parameters ==<br />
<br />
* *cmd holds '''ARGUMENT1'''...'''ARGUMENTN''' which have been passed along with the command<br />
* len is the length of the command (*cmd). Use this for securely parsing *cmd.<br />
* *output is the output buffer which can hold 50 bytes/characters<br />
<br />
== Return values ==<br />
{| border="1"<br />
| ECMD_FINAL_OK<br />
| the command has been executed without any errors. "OK" will be written to the caller's output.<br />
|-<br />
| ECMD_FINAL('''len''') <br />
| the command has been executed. '''len''' bytes of *output will be written to the caller's output<br />
|-<br />
| ECMD_AGAIN('''len''') <br />
| the command has been executed but needs to be called again. '''len''' bytes of *output will be written to the caller's output<br />
|-<br />
| ECMD_ERR_PARSE_ERROR <br />
| the command couldn't be executed (missing/wrong arguments etc.)<br />
|-<br />
| ECMD_ERR_READ_ERROR <br />
| the command couldn't be executed (not able to read from device/hardware)<br />
|-<br />
| ECMD_ERR_WRITE_ERROR <br />
| the command couldn't be executed (not able to write to device/hardware)<br />
|}<br />
== Announce the command ==<br />
<br />
Append this to the bottom of '''MODULENAME_ecmd.c''' to let the ECMD parser know<br />
about the new command.<br />
<source lang="c"><br />
/*<br />
-- Ethersex META --<br />
block(MODULENAME)<br />
ecmd_feature(FUNCTIONNAME, "COMMAND", ARGUMENT1...ARGUMENTN , DESCRIPTION)<br />
*/<br />
</source><br />
The '''COMMAND''' along with the arguments and the description will show up [[ECMD_Reference | here]]<br />
<br />
= Tips and best practice =<br />
<br />
== Recursive calling a command handler function ==<br />
<br />
If you need to output a lot of data (>50 bytes) , you need to recursivly call the command handler function<br />
using '''ECMD_AGAIN()'''.<br />
<br />
Instead of using unsafe ''static'' variables to keep track of the current progress you can use the following code:<br />
<source lang="c"><br />
/* trick: use bytes on cmd as "connection specific static variables" */<br />
if (cmd[0] != 23) { /* indicator flag: real invocation: 0 */<br />
cmd[0] = 23; /* continuing call: 23 */<br />
cmd[1] = 0; /* local variable 1 */<br />
}<br />
</source><br />
[https://github.com/ethersex/ethersex/blob/master/protocols/ecmd/parser.c#L193 source]<br />
[https://github.com/ethersex/ethersex/blob/master/services/dmx-storage/dmx_storage_ecmd.c#L105 example]<br />
[[Category:Development]]</div>Mgue