TCP message structure ===================== Main structure -------------- The structure of each packet is identical in both directions. The following scheme will be used for packet framing: .. image:: ../../pics/protocol/TF_protocol_structure.png | | **Packet framing control symbols:** | Each packet will always start with ``'\x02'`` and end with ``'\x03'``. | **Data block:** | UTF-8 encoded string that always contains a valid JSON string representing the data structure of the request or response, respectively. Structure of the request data block ----------------------------------- ``{"request": String(REQUESTED_TASK)}`` Legal values of ``"request"``: * ``"GetState"`` * ``"SystemStart"`` * ``"SystemStop"`` * ``"StartLogging"`` * ``"StopLogging"`` Structure of the response data block ------------------------------------ .. code-block:: { "status": Boolean(Is the request understood and processed), "response": OBJECT_REPRESENTING_RESULT } The ``"status"`` in the response will be set to **false** if there is a syntax error, a failure in TCP packet framing, an unrecognized request, or any other communication-related error. This can occur only if the sent request is malformed or if there are errors or data loss/corruption during transmission. If the packet framing fails, the server will not attempt to recover the communication on the current socket, as this could lead to undefined behavior. An error response will be sent, and the socket will be closed. |Company name| should then reestablish the connection. If an error occurs elsewhere (such as a JSON syntax error or an unrecognized command) and does not disrupt TCP packet framing, the response message will include the error. In this case, the socket will remain open, allowing communication to continue. If the request is successfully parsed and recognized, the ``"status"`` in the response will be set to **true**. The response will contain a ``"response"`` field, with its structure depending on the specific request that was sent. Bad request response object structure ------------------------------------- When a request is not recognized, ``"response"`` will contain a descriptive message: .. code-block:: { "message": String(free text comment explaining why request was not possible to process) } GetState response structure ---------------------------- When ``"GetState"`` is called, the ``"response"`` structure will contain the following message: .. code-block:: { "state": Integer(CURRENT_SYSTEM_STATE) "message": Optional-String(free text comment, for debugging/logging purposes) } Legal values of ``"state"`` (see :ref:`states and state switches ` for a more detailed explanation): * ``1`` when state is "CONNECTED" * ``2`` when state is "STARTING" * ``3`` when state is "NOT_LOGGING" * ``4`` when state is "LOGGING" * ``5`` when state is "STOPPING" * ``6-9`` undefined and reserved for later use * ``10`` when state is "ERROR" The ``"message"`` field, if present, provides a more detailed explanation of the state. Currently, it is used only in the "ERROR" state, but it may be incorporated for other states in the future. State switch request response ------------------------------ When ``"SystemStart"``, ``"SystemStop"``, ``"StartLogging"``, or ``"StopLogging"`` are called, ``"response"`` contains the following message: .. code-block:: { "success": Boolean(depending on the request's acceptance or rejection), "message": Optional-String(free text comment for debugging/logging purposes) } The field ``"success"`` is: * ``true`` when the request was accepted and is going to be performed. * ``false`` when for some reason the request was rejected and will not be performed. The ``"message"`` field is typically omitted when the request is successfully accepted. However, if the request is rejected, it will contain an explanation for the rejection. .. _TF_protocol_examples: Examples of full requests and their full responses --------------------------------------------------- * Ill formed request **Request:** ``{"request": "DoSomething"}`` **Response:** ``{"status": false, "response": {"message": "Task not recognized."}}`` * Ill formed request **Request:** ``{"req": "GetState"}`` **Response:** ``{"status": false, "response": {"message": "Bad request structure"}}`` * Ill formed request **Request:** ``{"request": "GetState"`` **Response:** ``{"status": false, "response": {"message": "JSON cannot be parsed."}}`` * Non-error state **Request:** ``{"request": "GetState"}`` **Response:** ``{"status": true, "response": {"state": 2}}`` * Error state **Request:** ``{"request": "GetState"}`` **Response:** ``{"status": true, "response": {"state": 10, "message": "Lidar storage full."}}`` * Successful request to switch state **Request:** ``{"request": "StartLogging"}`` **Response:** ``{"status": true, "response": {"success": true}}`` * Unsuccessful request to switch state **Request:** ``{"request": "StopLogging"}`` **Response:** ``{"status": true, "response": {"success": false, "message": "Current State STARTING is not appropriate to perform StopLogging."}}``