mirror of
https://github.com/obgm/libcoap.git
synced 2026-11-07 18:12:55 +03:00
156 lines
5.6 KiB
C
156 lines
5.6 KiB
C
/*
|
|
* coap_ws_internal.h -- WebSockets Transport Layer Support for libcoap
|
|
*
|
|
* Copyright (C) 2023-2024 Olaf Bergmann <bergmann@tzi.org>
|
|
* Copyright (C) 2023-2024 Jon Shallow <supjps-libcoap@jpshallow.com>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*
|
|
* This file is part of the CoAP library libcoap. Please see README for terms
|
|
* of use.
|
|
*/
|
|
|
|
/**
|
|
* @file coap_ws_internal.h
|
|
* @brief Internal CoAP WebSockets support
|
|
*/
|
|
|
|
#ifndef COAP_WS_INTERNAL_H_
|
|
#define COAP_WS_INTERNAL_H_
|
|
|
|
#include "coap_internal.h"
|
|
|
|
/**
|
|
* @ingroup internal_api
|
|
* @defgroup ws_internal WebSockets Support
|
|
* Internal API for WebSockets Support (RFC8323)
|
|
* @{
|
|
*/
|
|
|
|
|
|
/* Frame size: Min Header + (Opt) Ext payload length + (Opt) Masking key */
|
|
#define COAP_MAX_FS (2 + 8 + 4)
|
|
|
|
/**
|
|
* WebSockets session state
|
|
*/
|
|
typedef struct coap_ws_state_t {
|
|
coap_session_type_t state; /**< Client or Server */
|
|
uint8_t up; /**< WebSockets established */
|
|
uint8_t seen_first; /**< Seen first request/response HTTP header */
|
|
uint8_t seen_host; /**< Seen Host: HTTP header (server) */
|
|
uint8_t seen_upg; /**< Seen Upgrade: HTTP header */
|
|
uint8_t seen_conn; /**< Seen Connection: HTTP header */
|
|
uint8_t seen_key; /**< Seen Key: HTTP header */
|
|
uint8_t seen_proto; /**< Seen Protocol: HTTP header */
|
|
uint8_t seen_ver; /**< Seen version: HTTP header (server) */
|
|
uint8_t sent_close; /**< Close has been sent */
|
|
uint8_t recv_close; /**< Close has been received */
|
|
uint16_t close_reason; /**< Reason for closing */
|
|
int all_hdr_in; /**< Frame header available */
|
|
int hdr_ofs; /**< Current offset into rd_header */
|
|
uint8_t rd_header[COAP_MAX_FS]; /**< (Partial) frame */
|
|
uint8_t mask_key[4]; /**< Masking key */
|
|
uint32_t http_ofs; /**< Current offset into http_hdr */
|
|
uint8_t http_hdr[160]; /**< (Partial) HTTP header */
|
|
size_t data_ofs; /**< Offset into user provided buffer */
|
|
size_t data_size; /**< Data size as indicated by WebSocket frame */
|
|
uint8_t key[16]; /**< Random, but agreed key value */
|
|
} coap_ws_state_t;
|
|
|
|
/*
|
|
* WebSockets Frame
|
|
*
|
|
* 0 1 2 3
|
|
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
|
* +-+-+-+-+-------+-+-------------+-------------------------------+
|
|
* |F|R|R|R| opcode|M| Payload len | Extended payload length |
|
|
* |I|S|S|S| (4) |A| (7) | (16/64) |
|
|
* |N|V|V|V| |S| | (if payload len==126/127) |
|
|
* | |1|2|3| |K| | |
|
|
* +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|
|
* | Extended payload length continued, if payload len == 127 |
|
|
* + - - - - - - - - - - - - - - - +-------------------------------+
|
|
* | |Masking-key, if MASK set to 1 |
|
|
* +-------------------------------+-------------------------------+
|
|
* | Masking-key (continued) | Payload Data |
|
|
* +-------------------------------- - - - - - - - - - - - - - - - +
|
|
* : Payload Data continued ... :
|
|
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|
|
* | Payload Data continued ... |
|
|
* +---------------------------------------------------------------+
|
|
*/
|
|
|
|
#define WS_B0_FIN_BIT 0x80
|
|
#define WS_B0_RSV_MASK 0x70
|
|
#define WS_B0_OP_MASK 0x0f
|
|
|
|
#define WS_B1_MASK_BIT 0x80
|
|
#define WS_B1_LEN_MASK 0x7f
|
|
|
|
typedef enum {
|
|
WS_OP_CONT = 0x0,
|
|
WS_OP_TEXT,
|
|
WS_OP_BINARY,
|
|
WS_OP_CLOSE = 0x8,
|
|
WS_OP_PING,
|
|
WS_OP_PONG
|
|
} coap_ws_opcode_t;
|
|
|
|
/**
|
|
* Function interface for websockets data transmission. This function returns
|
|
* the number of bytes that have been transmitted, or a value less than zero
|
|
* on error. The number of bytes written may be less than datalen because of
|
|
* congestion control.
|
|
*
|
|
* @param session Session to send data on.
|
|
* @param data The data to send.
|
|
* @param datalen The actual length of @p data.
|
|
*
|
|
* @return The number of bytes written on success, or a value
|
|
* less than zero on error.
|
|
*/
|
|
ssize_t coap_ws_write(coap_session_t *session,
|
|
const uint8_t *data, size_t datalen);
|
|
|
|
/**
|
|
* Function interface for websockets data receiving. This function returns
|
|
* the number of bytes that have been read, or a value less than zero
|
|
* on error. The number of bytes read may be less than datalen because of
|
|
* congestion control.
|
|
*
|
|
* @param session Session to receive data on.
|
|
* @param data The data to receive.
|
|
* @param datalen The maximum length of @p data.
|
|
*
|
|
* @return The number of bytes read on success, or a value
|
|
* less than zero on error.
|
|
*/
|
|
ssize_t coap_ws_read(coap_session_t *session, uint8_t *data,
|
|
size_t datalen);
|
|
|
|
/**
|
|
* Layer function interface for layer below WebSockets accept/connect being
|
|
* established. This function initiates the WebSockets layer.
|
|
*
|
|
* If this layer is properly established on invocation, then the next layer
|
|
* must get called by calling
|
|
* session->lfunc[COAP_LAYER_WS].establish(session)
|
|
* (or done at any point when WebSockets is established).
|
|
*
|
|
* @param session Session that the lower layer accept/connect was done on.
|
|
*
|
|
*/
|
|
void coap_ws_establish(coap_session_t *session);
|
|
|
|
/**
|
|
* Layer function interface for WebSockets close for a session.
|
|
*
|
|
* @param session Session to do the WebSockets close on.
|
|
*/
|
|
void coap_ws_close(coap_session_t *session);
|
|
|
|
/** @} */
|
|
|
|
#endif /* COAP_WS_INTERNAL_H */
|