LCOV - code coverage report
Current view: top level - zephyr/shell - shell_websocket.h Coverage Total Hit
Test: new.info Lines: 41.9 % 31 13
Test Date: 2025-09-05 16:43:28

            Line data    Source code
       1            0 : /*
       2              :  * Copyright (c) 2024 Nordic Semiconductor ASA
       3              :  *
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : 
       7              : #ifndef ZEPHYR_INCLUDE_SHELL_WEBSOCKET_H_
       8              : #define ZEPHYR_INCLUDE_SHELL_WEBSOCKET_H_
       9              : 
      10              : #include <zephyr/net/socket.h>
      11              : #include <zephyr/net/http/server.h>
      12              : #include <zephyr/net/http/service.h>
      13              : #include <zephyr/shell/shell.h>
      14              : 
      15              : #ifdef __cplusplus
      16              : extern "C" {
      17              : #endif
      18              : 
      19            0 : #define SHELL_WEBSOCKET_SERVICE_COUNT CONFIG_SHELL_WEBSOCKET_BACKEND_COUNT
      20              : 
      21              : /** Line buffer structure. */
      22            1 : struct shell_websocket_line_buf {
      23              :         /** Line buffer. */
      24            1 :         char buf[CONFIG_SHELL_WEBSOCKET_LINE_BUF_SIZE];
      25              : 
      26              :         /** Current line length. */
      27            1 :         uint16_t len;
      28              : };
      29              : 
      30              : /** WEBSOCKET-based shell transport. */
      31            1 : struct shell_websocket {
      32              :         /** Handler function registered by shell. */
      33            1 :         shell_transport_handler_t shell_handler;
      34              : 
      35              :         /** Context registered by shell. */
      36            1 :         void *shell_context;
      37              : 
      38              :         /** Buffer for outgoing line. */
      39            1 :         struct shell_websocket_line_buf line_out;
      40              : 
      41              :         /** Array for sockets used by the websocket service. */
      42            1 :         struct zsock_pollfd fds[1];
      43              : 
      44              :         /** Input buffer. */
      45            1 :         uint8_t rx_buf[CONFIG_SHELL_CMD_BUFF_SIZE];
      46              : 
      47              :         /** Number of data bytes within the input buffer. */
      48            1 :         size_t rx_len;
      49              : 
      50              :         /** Mutex protecting the input buffer access. */
      51            1 :         struct k_mutex rx_lock;
      52              : 
      53              :         /** The delayed work is used to send non-lf terminated output that has
      54              :          *  been around for "too long". This will prove to be useful
      55              :          *  to send the shell prompt for instance.
      56              :          */
      57            1 :         struct k_work_delayable send_work;
      58            0 :         struct k_work_sync work_sync;
      59              : 
      60              :         /** If set, no output is sent to the WEBSOCKET client. */
      61            1 :         bool output_lock;
      62              : };
      63              : 
      64            0 : extern const struct shell_transport_api shell_websocket_transport_api;
      65            0 : int shell_websocket_setup(int ws_socket, struct http_request_ctx *request_ctx, void *user_data);
      66            0 : int shell_websocket_enable(const struct shell *sh);
      67              : 
      68            0 : #define GET_WS_NAME(_service) ws_ctx_##_service
      69            0 : #define GET_WS_SHELL_NAME(_name) shell_websocket_##_name
      70            0 : #define GET_WS_TRANSPORT_NAME(_service) transport_shell_ws_##_service
      71            0 : #define GET_WS_DETAIL_NAME(_service) ws_res_detail_##_service
      72              : 
      73            0 : #define SHELL_WEBSOCKET_DEFINE(_service)                                        \
      74              :         static struct shell_websocket GET_WS_NAME(_service);                    \
      75              :         static struct shell_transport GET_WS_TRANSPORT_NAME(_service) = {       \
      76              :                 .api = &shell_websocket_transport_api,                              \
      77              :                 .ctx = &GET_WS_NAME(_service),                                      \
      78              :         }
      79              : 
      80            0 : #define SHELL_WS_PORT_NAME(_service)    http_service_##_service
      81            0 : #define SHELL_WS_BUF_NAME(_service)     ws_recv_buffer_##_service
      82            0 : #define SHELL_WS_TEMP_RECV_BUF_SIZE 256
      83              : 
      84            0 : #define DEFINE_WEBSOCKET_HTTP_SERVICE(_service)                                 \
      85              :         uint8_t SHELL_WS_BUF_NAME(_service)[SHELL_WS_TEMP_RECV_BUF_SIZE];       \
      86              :         struct http_resource_detail_websocket                                   \
      87              :             GET_WS_DETAIL_NAME(_service) = {                                    \
      88              :                 .common = {                                                     \
      89              :                         .type = HTTP_RESOURCE_TYPE_WEBSOCKET,                   \
      90              :                                                                                 \
      91              :                         /* We need HTTP/1.1 GET method for upgrading */         \
      92              :                         .bitmask_of_supported_http_methods = BIT(HTTP_GET),     \
      93              :                 },                                                              \
      94              :                 .cb = shell_websocket_setup,                                    \
      95              :                 .data_buffer = SHELL_WS_BUF_NAME(_service),                     \
      96              :                 .data_buffer_len = sizeof(SHELL_WS_BUF_NAME(_service)),         \
      97              :                 .user_data = &GET_WS_NAME(_service),                                \
      98              :         };                                                                      \
      99              :         HTTP_RESOURCE_DEFINE(ws_resource_##_service, _service,                  \
     100              :                              "/" CONFIG_SHELL_WEBSOCKET_ENDPOINT_URL,         \
     101              :                              &GET_WS_DETAIL_NAME(_service))
     102              : 
     103            0 : #define DEFINE_WEBSOCKET_SERVICE(_service)                                      \
     104              :         SHELL_WEBSOCKET_DEFINE(_service);                                       \
     105              :         SHELL_DEFINE(shell_websocket_##_service,                                \
     106              :                      CONFIG_SHELL_WEBSOCKET_PROMPT,                             \
     107              :                      &GET_WS_TRANSPORT_NAME(_service),                              \
     108              :                      CONFIG_SHELL_WEBSOCKET_LOG_MESSAGE_QUEUE_SIZE,             \
     109              :                      CONFIG_SHELL_WEBSOCKET_LOG_MESSAGE_QUEUE_TIMEOUT,          \
     110              :                      SHELL_FLAG_OLF_CRLF);                                      \
     111              :         DEFINE_WEBSOCKET_HTTP_SERVICE(_service)
     112              : 
     113              : #if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)
     114              : /* Use a secure connection only for Websocket. */
     115              : #define WEBSOCKET_CONSOLE_DEFINE(_service, _sec_tag_list, _sec_tag_list_size) \
     116              :         static uint16_t SHELL_WS_PORT_NAME(_service) =                    \
     117              :                 CONFIG_SHELL_WEBSOCKET_PORT;                              \
     118              :         HTTPS_SERVICE_DEFINE(_service,                                    \
     119              :                              CONFIG_SHELL_WEBSOCKET_IP_ADDR,              \
     120              :                              &SHELL_WS_PORT_NAME(_service),           \
     121              :                              SHELL_WEBSOCKET_SERVICE_COUNT,               \
     122              :                              SHELL_WEBSOCKET_SERVICE_COUNT,               \
     123              :                              NULL,                                        \
     124              :                              NULL,                                        \
     125              :                              NULL,                                        \
     126              :                              _sec_tag_list,                               \
     127              :                              _sec_tag_list_size);                         \
     128              :         DEFINE_WEBSOCKET_SERVICE(_service);                               \
     129              : 
     130              : 
     131              : #else /* CONFIG_NET_SOCKETS_SOCKOPT_TLS */
     132              : /* TLS not possible so define only normal HTTP service */
     133            0 : #define WEBSOCKET_CONSOLE_DEFINE(_service, _sec_tag_list, _sec_tag_list_size) \
     134              :         static uint16_t SHELL_WS_PORT_NAME(_service) =                  \
     135              :                 CONFIG_SHELL_WEBSOCKET_PORT;                            \
     136              :         HTTP_SERVICE_DEFINE(_service,                                   \
     137              :                             CONFIG_SHELL_WEBSOCKET_IP_ADDR,             \
     138              :                             &SHELL_WS_PORT_NAME(_service),          \
     139              :                             SHELL_WEBSOCKET_SERVICE_COUNT,              \
     140              :                             SHELL_WEBSOCKET_SERVICE_COUNT,              \
     141              :                             NULL, NULL, NULL);                          \
     142              :         DEFINE_WEBSOCKET_SERVICE(_service)
     143              : 
     144              : #endif /* CONFIG_NET_SOCKETS_SOCKOPT_TLS */
     145              : 
     146            0 : #define WEBSOCKET_CONSOLE_ENABLE(_service)                              \
     147              :         (void)shell_websocket_enable(&GET_WS_SHELL_NAME(_service))
     148              : 
     149              : #ifdef __cplusplus
     150              : }
     151              : #endif
     152              : 
     153              : #endif /* ZEPHYR_INCLUDE_SHELL_WEBSOCKET_H_ */
        

Generated by: LCOV version 2.0-1