|
| 1 | +Monitor tools are a special kind of tool used to let the user communicate with the supported boards. A platform |
| 2 | +developer can create their own tools following the specification below. These tools must be in the form of command line |
| 3 | +executables that can be launched as a subprocess. |
| 4 | + |
| 5 | +They will communicate to the parent process via stdin/stdout, in particular a monitor tool will accept commands as plain |
| 6 | +text strings from stdin and will send answers back in JSON format on stdout. Each tool will implement the commands to |
| 7 | +open and control communication ports for a specific protocol as specified in this document. The actual I/O data stream |
| 8 | +from the communication port will be transferred to the parent process through a separate channel via TCP/IP. |
| 9 | + |
| 10 | +### Pluggable monitor API via stdin/stdout |
| 11 | + |
| 12 | +All the commands listed in this specification must be implemented in the monitor tool. |
| 13 | + |
| 14 | +After startup, the tool will just stay idle waiting for commands. The available commands are: `HELLO`, `DESCRIBE`, |
| 15 | +`CONFIGURE`, `OPEN`, `CLOSE` and `QUIT`. |
| 16 | + |
| 17 | +After each command the client always expects a response from the monitor. The monitor must not introduce any delay and |
| 18 | +must respond to all commands as fast as possible. |
| 19 | + |
| 20 | +#### HELLO command |
| 21 | + |
| 22 | +`HELLO` **must be the first command sent** to the monitor to tell the name of the client/IDE and the version of the |
| 23 | +pluggable monitor protocol that the client/IDE supports. The syntax of the command is: |
| 24 | + |
| 25 | +`HELLO <PROTOCOL_VERSION> "<USER_AGENT>"` |
| 26 | + |
| 27 | +- `<PROTOCOL_VERSION>` is the maximum protocol version supported by the client/IDE (currently `1`) |
| 28 | +- `<USER_AGENT>` is the name and version of the client. It must not contain double-quotes (`"`). |
| 29 | + |
| 30 | +some examples: |
| 31 | + |
| 32 | +- `HELLO 1 "Arduino IDE 1.8.13"` |
| 33 | + |
| 34 | +- `HELLO 1 "arduino-cli 1.2.3"` |
| 35 | + |
| 36 | +the response to the command is: |
| 37 | + |
| 38 | +```JSON |
| 39 | +{ |
| 40 | + "eventType": "hello", |
| 41 | + "protocolVersion": 1, |
| 42 | + "message": "OK" |
| 43 | +} |
| 44 | +``` |
| 45 | + |
| 46 | +The `protocolVersion` field represents the protocol version that will be used in the rest of the communication. There |
| 47 | +are three possible cases: |
| 48 | + |
| 49 | +- if the client/IDE supports the same or a more recent version of the protocol than the monitor tool, then the |
| 50 | + client/IDE should go into a compatibility mode and use the protocol level supported by the monitor tool. |
| 51 | +- if the monitor tool supports a more recent version of the protocol than the client/IDE, then the monitor tool should |
| 52 | + downgrade itself into compatibility mode and report a `protocolVersion` that is less than or equal to the one |
| 53 | + supported by the client/IDE. |
| 54 | +- if the monitor tool cannot go into compatibility mode, it must report the protocol version supported (even if greater |
| 55 | + than the version supported by the client/IDE) and the client/IDE may decide to terminate the monitor tool or produce |
| 56 | + an error/warning. |
| 57 | + |
| 58 | +#### DESCRIBE command |
| 59 | + |
| 60 | +The `DESCRIBE` command returns a description of the communication port. The description will have metadata about the |
| 61 | +port configuration, and which parameters are available to the user. |
| 62 | + |
| 63 | +```JSON |
| 64 | +{ |
| 65 | + "event": "describe", |
| 66 | + "message": "ok", |
| 67 | + "port_description": { |
| 68 | + "protocol": "serial", |
| 69 | + "configuration_parameters": { |
| 70 | + "baudrate": { |
| 71 | + "label": "Baudrate", |
| 72 | + "type": "enum", |
| 73 | + "values": [ |
| 74 | + "300", "600", "750", "1200", "2400", "4800", "9600", |
| 75 | + "19200", "38400", "57600", "115200", "230400", "460800", |
| 76 | + "500000", "921600", "1000000", "2000000" |
| 77 | + ], |
| 78 | + "selected": "9600" |
| 79 | + }, |
| 80 | + "parity": { |
| 81 | + "label": "Parity", |
| 82 | + "type": "enum", |
| 83 | + "values": [ "N", "E", "O", "M", "S" ], |
| 84 | + "selected": "N" |
| 85 | + }, |
| 86 | + "bits": { |
| 87 | + "label": "Data bits", |
| 88 | + "type": "enum", |
| 89 | + "values": [ "5", "6", "7", "8", "9" ], |
| 90 | + "selected": "8" |
| 91 | + }, |
| 92 | + "stop_bits": { |
| 93 | + "label": "Stop bits", |
| 94 | + "type": "enum", |
| 95 | + "values": [ "1", "1.5", "2" ], |
| 96 | + "selected": "1" |
| 97 | + } |
| 98 | + } |
| 99 | + } |
| 100 | +} |
| 101 | +``` |
| 102 | + |
| 103 | +The field `protocol` is the board port protocol identifier, it must match with the corresponding protocol identifier for |
| 104 | +a pluggable discovery tool. |
| 105 | + |
| 106 | +`configuration_parameters` is a key/value map that enumerates the available port parameters. |
| 107 | + |
| 108 | +Each parameter has a unique name (`baudrate`, `parity`, etc...), a `type` (in this case only `enum` is allowed but more |
| 109 | +types may be added in the future if needed), and the `selected` value for each parameter. |
| 110 | + |
| 111 | +The parameter name can not contain spaces, the allowed characters are alphanumerics, underscore `_`, dot `.`, and dash |
| 112 | +`-`. |
| 113 | + |
| 114 | +The `enum` types must have a list of possible `values`. |
| 115 | + |
| 116 | +The client/IDE may expose these configuration values to the user via a config file or a GUI, in this case the `label` |
| 117 | +field may be used for a user readable description of the parameter. |
| 118 | + |
| 119 | +#### CONFIGURE command |
| 120 | + |
| 121 | +The `CONFIGURE` command sets configuration parameters for the communication port. The parameters can be changed one at a |
| 122 | +time and the syntax is: |
| 123 | + |
| 124 | +`CONFIGURE <PARAMETER_NAME> <VALUE>` |
| 125 | + |
| 126 | +The response to the command is: |
| 127 | + |
| 128 | +```JSON |
| 129 | +{ |
| 130 | + "event": "configure", |
| 131 | + "message": "ok", |
| 132 | +} |
| 133 | +``` |
| 134 | + |
| 135 | +or if there is an error: |
| 136 | + |
| 137 | +```JSON |
| 138 | +{ |
| 139 | + "event": "configure", |
| 140 | + "error": true, |
| 141 | + "message": "invalid value for parameter baudrate: 123456" |
| 142 | +} |
| 143 | +``` |
| 144 | + |
| 145 | +The currently selected parameters or their default value may be obtained using the `DESCRIBE` command. |
| 146 | + |
| 147 | +#### OPEN command |
| 148 | + |
| 149 | +The `OPEN` command opens a communication port with the board, the data exchanged with the board will be transferred to |
| 150 | +the Client/IDE via TCP/IP. |
| 151 | + |
| 152 | +The Client/IDE must first TCP-Listen to a randomly selected TCP port and send the address to connect it to the monitor |
| 153 | +tool as part of the `OPEN` command. The syntax of the `OPEN` command is: |
| 154 | + |
| 155 | +`OPEN <CLIENT_TCPIP_ADDRESS> <BOARD_PORT>` |
| 156 | + |
| 157 | +For example, let's suppose that the Client/IDE wants to communicate with the serial port `/dev/ttyACM0` using an |
| 158 | +hypotetical `serial-monitor` tool, then the sequence of actions to perform will be the following: |
| 159 | + |
| 160 | +1. the Client/IDE must first listen to a random TCP port (let's suppose it chose `32123`) |
| 161 | +1. the Client/IDE runs the `serial-monitor` tool and initialize it with the `HELLO` command |
| 162 | +1. the Client/IDE sends the command `OPEN 127.0.0.1:32123 /dev/ttyACM0` to the monitor tool |
| 163 | +1. the monitor tool opens `/dev/ttyACM0` |
| 164 | +1. the monitor tool connects via TCP/IP to `127.0.0.1:32123` and start streaming data back and forth |
| 165 | + |
| 166 | +The answer to the `OPEN` command is: |
| 167 | + |
| 168 | +```JSON |
| 169 | +{ |
| 170 | + "event": "open", |
| 171 | + "message": "ok" |
| 172 | +} |
| 173 | +``` |
| 174 | + |
| 175 | +If the monitor tool cannot communicate with the board, or if the tool can not connect back to the TCP port, or if any |
| 176 | +other error condition happens: |
| 177 | + |
| 178 | +```JSON |
| 179 | +{ |
| 180 | + "event": "open", |
| 181 | + "error": true, |
| 182 | + "message": "unknown port /dev/ttyACM23" |
| 183 | +} |
| 184 | +``` |
| 185 | + |
| 186 | +The board port will be opened using the parameters previously set through the `CONFIGURE` command. |
| 187 | + |
| 188 | +Once the port is opened, it may be unexpectedly closed at any time due to hardware failure, or because the Client/IDE |
| 189 | +closes the TCP/IP connection, etc. In this case an asynchronous `port_closed` message must be generated from the monitor |
| 190 | +tool: |
| 191 | + |
| 192 | +```JSON |
| 193 | +{ |
| 194 | + "event": "port_closed", |
| 195 | + "message": "serial port disappeared!" |
| 196 | +} |
| 197 | +``` |
| 198 | + |
| 199 | +or |
| 200 | + |
| 201 | +```JSON |
| 202 | +{ |
| 203 | + "event": "port_closed", |
| 204 | + "message": "lost TCP/IP connection with the client!" |
| 205 | +} |
| 206 | +``` |
| 207 | + |
| 208 | +#### CLOSE command |
| 209 | + |
| 210 | +The `CLOSE` command will close the currently opened port and close the TCP/IP connection used to communicate with the |
| 211 | +Client/IDE. The answer to the command is: |
| 212 | + |
| 213 | +```JSON |
| 214 | +{ |
| 215 | + "event": "close", |
| 216 | + "message": "ok" |
| 217 | +} |
| 218 | +``` |
| 219 | + |
| 220 | +or in case of error |
| 221 | + |
| 222 | +```JSON |
| 223 | +{ |
| 224 | + "event": "close", |
| 225 | + "error": true, |
| 226 | + "message": "port already closed" |
| 227 | +} |
| 228 | +``` |
| 229 | + |
| 230 | +#### QUIT command |
| 231 | + |
| 232 | +The `QUIT` command terminates the monitor. The response to `QUIT` is: |
| 233 | + |
| 234 | +```JSON |
| 235 | +{ |
| 236 | + "eventType": "quit", |
| 237 | + "message": "OK" |
| 238 | +} |
| 239 | +``` |
| 240 | + |
| 241 | +after this output the monitor exits. This command is supposed to always succeed. |
| 242 | + |
| 243 | +#### Invalid commands |
| 244 | + |
| 245 | +If the client sends an invalid or malformed command, the monitor should answer with: |
| 246 | + |
| 247 | +```JSON |
| 248 | +{ |
| 249 | + "eventType": "command_error", |
| 250 | + "error": true, |
| 251 | + "message": "Unknown command XXXX" |
| 252 | +} |
| 253 | +``` |
0 commit comments