<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://www.ethersex.de/index.php?action=history&amp;feed=atom&amp;title=Development%2FECMD</id>
		<title>Development/ECMD - Revision history</title>
		<link rel="self" type="application/atom+xml" href="http://www.ethersex.de/index.php?action=history&amp;feed=atom&amp;title=Development%2FECMD"/>
		<link rel="alternate" type="text/html" href="http://www.ethersex.de/index.php?title=Development/ECMD&amp;action=history"/>
		<updated>2026-05-25T05:01:46Z</updated>
		<subtitle>Revision history for this page on the wiki</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://www.ethersex.de/index.php?title=Development/ECMD&amp;diff=790&amp;oldid=prev</id>
		<title>Atos: /* Parameters */</title>
		<link rel="alternate" type="text/html" href="http://www.ethersex.de/index.php?title=Development/ECMD&amp;diff=790&amp;oldid=prev"/>
				<updated>2012-07-26T03:33:26Z</updated>
		
		<summary type="html">&lt;p&gt;‎&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Parameters&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr style=&quot;vertical-align: top;&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;Revision as of 03:33, 26 July 2012&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l31&quot; &gt;Line 31:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 31:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;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;&quot;&gt;&lt;div&gt;== Parameters ==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;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;&quot;&gt;&lt;div&gt;== Parameters ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;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;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;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;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;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;&quot;&gt;&lt;div&gt;* *cmd holds '''ARGUMENT1'''...'''ARGUMENTN'''&amp;#160; which have been passed along with the command&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;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;&quot;&gt;&lt;div&gt;* *cmd holds '''ARGUMENT1'''...'''ARGUMENTN'''&amp;#160; which have been passed along with the command&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;. 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.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;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;&quot;&gt;&lt;div&gt;* len is the length of the command (*cmd). Use this for securely parsing *cmd.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;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;&quot;&gt;&lt;div&gt;* &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;strike&amp;gt;&lt;/ins&gt;len is the length of the command (*cmd). Use this for securely parsing *cmd&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;.&amp;lt;/strike&amp;gt; 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&lt;/ins&gt;. &amp;#160;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;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;&quot;&gt;&lt;div&gt;* *output is the output buffer which can hold 50 bytes/characters&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;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;&quot;&gt;&lt;div&gt;* *output is the output buffer &lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;strike&amp;gt;&lt;/ins&gt;which can hold 50 bytes/characters&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;&amp;lt;/strike&amp;gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;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;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;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;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;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;&quot;&gt;&lt;div&gt;== Return values ==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;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;&quot;&gt;&lt;div&gt;== Return values ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key sensrjeb_etherwiki:diff:version:1.11a:oldid:410:newid:790 --&gt;
&lt;/table&gt;</summary>
		<author><name>Atos</name></author>	</entry>

	<entry>
		<id>http://www.ethersex.de/index.php?title=Development/ECMD&amp;diff=410&amp;oldid=prev</id>
		<title>Mgue: first version</title>
		<link rel="alternate" type="text/html" href="http://www.ethersex.de/index.php?title=Development/ECMD&amp;diff=410&amp;oldid=prev"/>
				<updated>2012-03-27T18:29:16Z</updated>
		
		<summary type="html">&lt;p&gt;first version&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{i18n|Development/ECMD}}&lt;br /&gt;
For general information on ECMD, see [[ECMD]].&lt;br /&gt;
&lt;br /&gt;
The following variables will be used on this page. Replace them for your module.&lt;br /&gt;
&lt;br /&gt;
* '''COMMAND''' - how the command will be invoked&lt;br /&gt;
* '''ARGUMENT1'''...'''ARGUMENTN''' - the arguments that will be passed together with '''COMMAND'''&lt;br /&gt;
* '''FUNCTIONNAME''' - the name of the function which will handle the command&lt;br /&gt;
* '''MODULENAME''' - the name of the module&lt;br /&gt;
&lt;br /&gt;
= Preparations =&lt;br /&gt;
&lt;br /&gt;
* Create a new file inside the folder of the module '''MODULENAME_ecmd.c'''&lt;br /&gt;
* Add this file to the [[Development/Makefile | Makefile]] of the module.&lt;br /&gt;
* Open the file and &amp;quot;#include &amp;quot;protocols/ecmd/ecmd-base.h&amp;quot; and other necessary headers.&lt;br /&gt;
* Add the header of the module, &amp;lt;string.h&amp;gt; etc.&lt;br /&gt;
&lt;br /&gt;
= Create a new command =&lt;br /&gt;
&lt;br /&gt;
Start with the following template:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int16_t parse_cmd_FUNCTIONNAME (char *cmd, char *output, uint16_t len)&lt;br /&gt;
{&lt;br /&gt;
        /* Your Code here */&lt;br /&gt;
	return ECMD_FINAL_OK;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Whenever '''COMMAND''' is invoked, this function will be called to handle it.&lt;br /&gt;
&lt;br /&gt;
== Parameters ==&lt;br /&gt;
&lt;br /&gt;
* *cmd holds '''ARGUMENT1'''...'''ARGUMENTN'''  which have been passed along with the command&lt;br /&gt;
* len is the length of the command (*cmd). Use this for securely parsing *cmd.&lt;br /&gt;
* *output is the output buffer which can hold 50 bytes/characters&lt;br /&gt;
&lt;br /&gt;
== Return values ==&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
| ECMD_FINAL_OK&lt;br /&gt;
| the command has been executed without any errors. &amp;quot;OK&amp;quot; will be written to the caller's output.&lt;br /&gt;
|-&lt;br /&gt;
| ECMD_FINAL('''len''') &lt;br /&gt;
| the command has been executed. '''len''' bytes of *output will be written to the caller's output&lt;br /&gt;
|-&lt;br /&gt;
| ECMD_AGAIN('''len''') &lt;br /&gt;
| the command has been executed but needs to be called again. '''len''' bytes of *output will be written to the caller's output&lt;br /&gt;
|-&lt;br /&gt;
| ECMD_ERR_PARSE_ERROR &lt;br /&gt;
| the command couldn't be executed (missing/wrong arguments etc.)&lt;br /&gt;
|-&lt;br /&gt;
| ECMD_ERR_READ_ERROR &lt;br /&gt;
| the command couldn't be executed (not able to read from device/hardware)&lt;br /&gt;
|-&lt;br /&gt;
| ECMD_ERR_WRITE_ERROR &lt;br /&gt;
| the command couldn't be executed (not able to write to device/hardware)&lt;br /&gt;
|}&lt;br /&gt;
== Announce the command ==&lt;br /&gt;
&lt;br /&gt;
Append this to the bottom of '''MODULENAME_ecmd.c''' to let the ECMD parser know&lt;br /&gt;
about the new command.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
-- Ethersex META --&lt;br /&gt;
block(MODULENAME)&lt;br /&gt;
ecmd_feature(FUNCTIONNAME, &amp;quot;COMMAND&amp;quot;, ARGUMENT1...ARGUMENTN , DESCRIPTION)&lt;br /&gt;
*/&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The '''COMMAND''' along with the arguments and the description will show up [[ECMD_Reference | here]]&lt;br /&gt;
&lt;br /&gt;
= Tips and best practice =&lt;br /&gt;
&lt;br /&gt;
== Recursive calling a command handler function ==&lt;br /&gt;
&lt;br /&gt;
If you need to output a lot of data (&amp;gt;50 bytes) , you need to recursivly call the command handler function&lt;br /&gt;
using '''ECMD_AGAIN()'''.&lt;br /&gt;
&lt;br /&gt;
Instead of using unsafe ''static'' variables to keep track of the current progress you can use the following code:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 /* trick: use bytes on cmd as &amp;quot;connection specific static variables&amp;quot; */&lt;br /&gt;
    if (cmd[0] != 23) {		/* indicator flag: real invocation:  0 */&lt;br /&gt;
	cmd[0] = 23;		/*                 continuing call: 23 */&lt;br /&gt;
	cmd[1] = 0;		/* local variable 1 */&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
[https://github.com/ethersex/ethersex/blob/master/protocols/ecmd/parser.c#L193 source]&lt;br /&gt;
[https://github.com/ethersex/ethersex/blob/master/services/dmx-storage/dmx_storage_ecmd.c#L105 example]&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Mgue</name></author>	</entry>

	</feed>