WebSocketsinC  0.2.1
Function List | Macros | Typedefs
WIC

Description

WIC provides everything needed to turn a TCP/TLS socket into a Websocket.

Function List

bool wic_init (struct wic_inst *self, const struct wic_init_arg *arg)
 
void * wic_get_app (struct wic_inst *self)
 
const char * wic_get_url (const struct wic_inst *self)
 
uint16_t wic_get_status_code (const struct wic_inst *self)
 
const char * wic_get_url_hostname (const struct wic_inst *self)
 
uint16_t wic_get_url_port (const struct wic_inst *self)
 
enum wic_schema wic_get_url_schema (const struct wic_inst *self)
 
const char * wic_get_redirect_url (const struct wic_inst *self)
 
enum wic_status wic_start (struct wic_inst *self)
 
size_t wic_parse (struct wic_inst *self, const void *data, size_t size)
 
void wic_close (struct wic_inst *self)
 
void wic_close_with_reason (struct wic_inst *self, uint16_t code, const char *reason, uint16_t size)
 
enum wic_status wic_send_binary (struct wic_inst *self, bool fin, const void *data, uint16_t size)
 
enum wic_status wic_send_text (struct wic_inst *self, bool fin, const char *data, uint16_t size)
 
enum wic_status wic_send (struct wic_inst *self, enum wic_encoding encoding, bool fin, const char *data, uint16_t size)
 
enum wic_status wic_send_ping (struct wic_inst *self)
 
enum wic_status wic_send_ping_with_payload (struct wic_inst *self, const void *data, uint16_t size)
 
bool wic_set_header (struct wic_inst *self, struct wic_header *header)
 
const char * wic_get_header (const struct wic_inst *self, const char *name)
 
const char * wic_get_next_header (struct wic_inst *self, const char **name)
 
void wic_rewind_get_next_header (struct wic_inst *self)
 
enum wic_state wic_get_state (const struct wic_inst *self)
 

Macros

#define WIC_PORT_INCLUDE
 
#define WIC_DEBUG(...)
 
#define WIC_ERROR(...)
 
#define WIC_ASSERT(XX)
 
#define WIC_HOSTNAME_MAXLEN   256U
 
#define WIC_CLOSE_NORMAL   1000U
 
#define WIC_CLOSE_GOING_AWAY   1001U
 
#define WIC_CLOSE_PROTOCOL_ERROR   1002U
 
#define WIC_CLOSE_UNSUPPORTED   1003U
 
#define WIC_CLOSE_INVALID_DATA   1007U
 
#define WIC_CLOSE_POLICY   1008U
 
#define WIC_CLOSE_TOO_BIG   1009U
 
#define WIC_CLOSE_EXTENSION_REQUIRED   1010U
 
#define WIC_CLOSE_UNEXPECTED_EXCEPTION   1011U
 
#define WIC_CLOSE_ABNORMAL_1   1005U
 
#define WIC_CLOSE_ABNORMAL_2   1006U
 
#define WIC_CLOSE_TLS   1015U
 

Typedefs

typedef bool(* wic_on_message_fn) (struct wic_inst *inst, enum wic_encoding encoding, bool fin, const char *data, uint16_t size)
 
typedef void(* wic_on_open_fn) (struct wic_inst *inst)
 
typedef void(* wic_on_handshake_failure_fn) (struct wic_inst *inst, enum wic_handshake_failure reason)
 
typedef void(* wic_on_close_fn) (struct wic_inst *inst, uint16_t code, const char *reason, uint16_t size)
 
typedef void(* wic_on_close_transport_fn) (struct wic_inst *inst)
 
typedef void(* wic_on_send_fn) (struct wic_inst *inst, const void *data, size_t size, enum wic_buffer type)
 
typedef void *(* wic_on_buffer_fn) (struct wic_inst *inst, size_t min_size, enum wic_buffer type, size_t *max_size)
 
typedef uint32_t(* wic_rand_fn) (struct wic_inst *inst)
 
typedef void(* wic_on_ping_fn) (struct wic_inst *inst)
 
typedef void(* wic_on_pong_fn) (struct wic_inst *inst)
 

Functions

◆ wic_init()

bool wic_init ( struct wic_inst self,
const struct wic_init_arg arg 
)

Initialise an instance.

Parameters
[in]self
[in]argwic_init_arg
Return values
trueinstance has been initialised
false

◆ wic_get_app()

void* wic_get_app ( struct wic_inst self)

Get pointer to application specific data.

Parameters
[in]self
Returns
pointer

◆ wic_get_url()

const char* wic_get_url ( const struct wic_inst self)

Get URL string.

Parameters
[in]self
Returns
null-terminated URL

◆ wic_get_status_code()

uint16_t wic_get_status_code ( const struct wic_inst self)

Get status code of handshake.

Parameters
[in]self
Return values
0status not set

◆ wic_get_url_hostname()

const char* wic_get_url_hostname ( const struct wic_inst self)

Get URL hostname string.

Parameters
[in]self
Returns
null-terminated hostname
Return values
NULLURL not set

◆ wic_get_url_port()

uint16_t wic_get_url_port ( const struct wic_inst self)

Get URL port number.

Parameters
[in]self
Returns
port number

◆ wic_get_url_schema()

enum wic_schema wic_get_url_schema ( const struct wic_inst self)

Get URL schema.

Parameters
[in]self
Returns
wic_schema

◆ wic_get_redirect_url()

const char* wic_get_redirect_url ( const struct wic_inst self)

Get a redirect URL if the server handshake response was a valid redirect.

Parameters
[in]self
Returns
valid null-terminated URL
Return values
NULLno redirection URL is available

◆ wic_start()

enum wic_status wic_start ( struct wic_inst self)

Start instance.

Parameters
[in]self
Returns
wic_status

◆ wic_parse()

size_t wic_parse ( struct wic_inst self,
const void *  data,
size_t  size 
)

Receive data from socket.

Parameters
[in]self
[in]data
[in]sizesize of data
Returns
bytes parsed

This function will parse one wic frame or message at a time. It is the responsibility of the integrator to track how many bytes have been consumed, and to call wic_parse again to continue parsing.

If no bytes are consumed it means that wic_inst is either blocked (see wic_on_message_fn) or that wic_inst has entered closed state.

◆ wic_close()

void wic_close ( struct wic_inst self)

Normal close (1000)

Note
it is OK to call wic_close() even if already closed
Parameters
[in]self
See also
wic_close_with_reason()

◆ wic_close_with_reason()

void wic_close_with_reason ( struct wic_inst self,
uint16_t  code,
const char *  reason,
uint16_t  size 
)

Close with specific code and reason.

Note
it is OK to call close_with_reason() even if already closed
Parameters
[in]self
[in]codewebsocket close code
[in]reasonUTF8 encoded string
[in]sizesize of reason

RFC6455 defines the following codes:

◆ wic_send_binary()

enum wic_status wic_send_binary ( struct wic_inst self,
bool  fin,
const void *  data,
uint16_t  size 
)

Equivalent to calling wic_send() with WIC_ENCODING_BINARY encoding.

◆ wic_send_text()

enum wic_status wic_send_text ( struct wic_inst self,
bool  fin,
const char *  data,
uint16_t  size 
)

Equivalent to calling wic_send() with WIC_ENCODING_UTF8 encoding.

◆ wic_send()

enum wic_status wic_send ( struct wic_inst self,
enum wic_encoding  encoding,
bool  fin,
const char *  data,
uint16_t  size 
)

Send a message with either UTF or binary encoding.

Parameters
[in]self
[in]encodingencoding of data
[in]fintrue if final fragment
[in]data
[in]sizesize of data
Returns
wic_status
Return values
WIC_STATUS_SUCCESS
WIC_STATUS_NOT_OPEN
WIC_STATUS_WOULD_BLOCK
WIC_STATUS_TOO_LARGE

◆ wic_send_ping()

enum wic_status wic_send_ping ( struct wic_inst self)

Send a Ping message.

A peer will answer a Ping with a Pong. This is useful for implementing a confirmed "keep alive" feature.

Parameters
[in]self
Returns
wic_status
Return values
WIC_STATUS_SUCCESS
WIC_STATUS_NOT_OPEN
WIC_STATUS_WOULD_BLOCK
WIC_STATUS_TOO_LARGE
See also
wic_send_ping_with_payload().

◆ wic_send_ping_with_payload()

enum wic_status wic_send_ping_with_payload ( struct wic_inst self,
const void *  data,
uint16_t  size 
)

Send a Ping message with application data.

Parameters
[in]self
[in]data
[in]sizesize of data
Returns
wic_status
Return values
WIC_STATUS_SUCCESS
WIC_STATUS_NOT_OPEN
WIC_STATUS_WOULD_BLOCK
WIC_STATUS_TOO_LARGE
See also
wic_send_ping()

◆ wic_set_header()

bool wic_set_header ( struct wic_inst self,
struct wic_header header 
)

Set a header key-value that will be either sent as either:

  1. A client handshake request
  2. A server handshake response
Note
wic_get_header() does not return headers previously set by wic_set_header(), it returns headers set by the peer
Warning
it is the responsibility of the application to ensure header memory remains valid for lifetime of wic_inst
Parameters
[in]self
[in]headerwic_header
Return values
trueheader linked
false

◆ wic_get_header()

const char* wic_get_header ( const struct wic_inst self,
const char *  name 
)

Get a value for a given header.

If instance is initialised as a client, this function will get headers sent by the server.

If instance is intialised as a server, this function will get headers sent by the client.

Parameters
[in]self
[in]namenull-terminated key/name
Returns
null-terminated value

◆ wic_get_next_header()

const char* wic_get_next_header ( struct wic_inst self,
const char **  name 
)

Call successively to get the next header.

Depends on iterator state within instance. Use wic_rewind_get_next_header() to reset the iterator at any time.

Parameters
[in]self
[out]namenull-terminated key/name
Returns
null-terminated value
Return values
NULLno next header

◆ wic_rewind_get_next_header()

void wic_rewind_get_next_header ( struct wic_inst self)

Rewind the iterator state used by wic_get_next_header()

Parameters
[in]self

◆ wic_get_state()

enum wic_state wic_get_state ( const struct wic_inst self)

Get instance state.

Parameters
[in]self
Returns
wic_state

Data Structure Documentation

◆ wic_init_arg

struct wic_init_arg

wic_init() argument

Data Fields

void * rx
 
size_t rx_max
 
wic_on_message_fn on_message
 
wic_on_open_fn on_open
 
wic_on_close_fn on_close
 
wic_on_close_transport_fn on_close_transport
 
wic_on_handshake_failure_fn on_handshake_failure
 
wic_on_ping_fn on_ping
 
wic_on_pong_fn on_pong
 
wic_rand_fn rand
 
wic_on_send_fn on_send
 
wic_on_buffer_fn on_buffer
 
void * app
 
const char * url
 
enum wic_role role
 

Field Documentation

◆ rx

void* wic_init_arg::rx

Buffer used to store received frame payload and received handshake.

◆ rx_max

size_t wic_init_arg::rx_max

Maximum size of rx payload and received handshake.

◆ on_message

wic_on_message_fn wic_init_arg::on_message

OPTIONAL handler called when text or binary is received

◆ on_open

wic_on_open_fn wic_init_arg::on_open

OPTIONAL handler called when socket becomes open/established

◆ on_close

wic_on_close_fn wic_init_arg::on_close

OPTIONAL handler called when open/established socket becomes closed

◆ on_close_transport

wic_on_close_transport_fn wic_init_arg::on_close_transport

OPTIONAL handler called underlying transport should be closed

◆ on_handshake_failure

wic_on_handshake_failure_fn wic_init_arg::on_handshake_failure

OPTIONAL handler called when handshake fails

◆ on_ping

wic_on_ping_fn wic_init_arg::on_ping

OPTIONAL handler called when ping is received

◆ on_pong

wic_on_pong_fn wic_init_arg::on_pong

OPTIONAL handler called when pong is received

◆ rand

wic_rand_fn wic_init_arg::rand

OPTIONAL handler called to get a random number

◆ on_send

wic_on_send_fn wic_init_arg::on_send

handler called to write message to transport

◆ on_buffer

wic_on_buffer_fn wic_init_arg::on_buffer

handler called to get a buffer (prior to calling wic_init_arg.on_send)

◆ app

void* wic_init_arg::app

OPTIONAL any data you wish to associate with instance

◆ url

const char* wic_init_arg::url

OPTIONAL null-terminated URL required for client role

◆ role

enum wic_role wic_init_arg::role

instance can be client or server

◆ wic_header

struct wic_header

Structure used to link headers with wic_inst.

Data Fields

const char * name
 
const char * value
 

Field Documentation

◆ name

const char* wic_header::name

null-terminated key/name

◆ value

const char* wic_header::value

null-terminated value

◆ wic_inst

struct wic_inst

WIC instance.

Macro Definition Documentation

◆ WIC_PORT_INCLUDE

#define WIC_PORT_INCLUDE

a filename to be included by the preprocessor

e.g.

-D'WIC_PORT_INCLUDE="port.h"'

◆ WIC_DEBUG

#define WIC_DEBUG (   ...)

print a debug level message

e.g.

#define WIC_DEBUG(...) do{printf("debug: ");printf(__VA_ARGS__);printf("\n");}while(0);

◆ WIC_ERROR

#define WIC_ERROR (   ...)

print an error level message

e.g.

#define WIC_ERROR(...) do{printf("error: ");printf(__VA_ARGS__);printf("\n");}while(0);

◆ WIC_ASSERT

#define WIC_ASSERT (   XX)

assert XX is true

e.g.

#define WIC_ASSERT(XX) assert(XX);

◆ WIC_HOSTNAME_MAXLEN

#define WIC_HOSTNAME_MAXLEN   256U

redefine size of wic_inst hostname buffer

◆ WIC_CLOSE_NORMAL

#define WIC_CLOSE_NORMAL   1000U

the purpose for which the connection was established has been fulfilled

◆ WIC_CLOSE_GOING_AWAY

#define WIC_CLOSE_GOING_AWAY   1001U

endpoint is going away

◆ WIC_CLOSE_PROTOCOL_ERROR

#define WIC_CLOSE_PROTOCOL_ERROR   1002U

protocol error

◆ WIC_CLOSE_UNSUPPORTED

#define WIC_CLOSE_UNSUPPORTED   1003U

endpoint has received an opcode it doesn't support

◆ WIC_CLOSE_INVALID_DATA

#define WIC_CLOSE_INVALID_DATA   1007U

data received in message not consistent with type of message (e.g.

invalid UTF8)

◆ WIC_CLOSE_POLICY

#define WIC_CLOSE_POLICY   1008U

message received violates endpoint policy

◆ WIC_CLOSE_TOO_BIG

#define WIC_CLOSE_TOO_BIG   1009U

message is too large to receive

◆ WIC_CLOSE_EXTENSION_REQUIRED

#define WIC_CLOSE_EXTENSION_REQUIRED   1010U

extension is required

◆ WIC_CLOSE_UNEXPECTED_EXCEPTION

#define WIC_CLOSE_UNEXPECTED_EXCEPTION   1011U

some other unexpected exception

◆ WIC_CLOSE_ABNORMAL_1

#define WIC_CLOSE_ABNORMAL_1   1005U

abnormal closure #1 (application specific meaning)

◆ WIC_CLOSE_ABNORMAL_2

#define WIC_CLOSE_ABNORMAL_2   1006U

abnormal closure #2 (application specific meaning)

◆ WIC_CLOSE_TLS

#define WIC_CLOSE_TLS   1015U

TLS specific abornmal closure.

Typedef Documentation

◆ wic_on_message_fn

typedef bool(* wic_on_message_fn) (struct wic_inst *inst, enum wic_encoding encoding, bool fin, const char *data, uint16_t size)

Binary or UTF8 message received.

Parameters
[in]inst
[in]encodingbinary or utf8
[in]fintrue if the final fragment
[in]data
[in]sizesize of data
Return values
truemessage accepted
falsehost is blocked and cannot receive

This function has a return value to indicate if the host was ready to accept the message. If the host returns false the message will remain buffered in wic_inst and will be passed to this function next time wic_parse is called.

The behaviour can be used to implement 'back-pressure' on messages received. For example, the host may queue received messages and the queue may become full. In this situation wic should block (i.e. stop parsing new input data) to ensure that messages are not dropped.

◆ wic_on_open_fn

typedef void(* wic_on_open_fn) (struct wic_inst *inst)

Websocket open event.

Regardless of role, wic_get_state() called from this handler will return WIC_STATE_READY. This means, among other things, that handshake fields from the peer are accessible.

If inst is a server, this handler must call wic_start() in order to send the handshake response and open the websocket.

Parameters
[in]inst

◆ wic_on_handshake_failure_fn

typedef void(* wic_on_handshake_failure_fn) (struct wic_inst *inst, enum wic_handshake_failure reason)

Handshake failed event.

Parameters
[in]inst
[in]reason

◆ wic_on_close_fn

typedef void(* wic_on_close_fn) (struct wic_inst *inst, uint16_t code, const char *reason, uint16_t size)

Websocket closed event.

The websocket was previously open, this message indicates that it is now closed.

Parameters
[in]inst
[in]code
[in]reasonoptional UTF8 string explaining the reason for close
[in]sizesize of reason

◆ wic_on_close_transport_fn

typedef void(* wic_on_close_transport_fn) (struct wic_inst *inst)

Close transport event.

Use this event to close the underlying transport.

Parameters
[in]inst

◆ wic_on_send_fn

typedef void(* wic_on_send_fn) (struct wic_inst *inst, const void *data, size_t size, enum wic_buffer type)

Release buffer by sending it.

If size is zero, it means WIC is releasing a buffer but not sending anything.

Parameters
[in]inst
[in]data
[in]sizesize of data (may be zero)
[in]typemay be used for prioritisation

◆ wic_on_buffer_fn

typedef void*(* wic_on_buffer_fn) (struct wic_inst *inst, size_t min_size, enum wic_buffer type, size_t *max_size)

Get a buffer of a minimum size for transporting a particular frame type.

If WIC does not know the size required, it will set min_size to 0. This means provide the largest buffer. At the moment this only happens during the handshake (i.e. type == WIC_FRAME_TYPE_HTTP).

wic_on_send_fn will always be called after this handler. This is this is to provide an opportunity to free any allocates made in this handler.

Parameters
[in]inst
[in]min_sizebuffer should be at least this size
[in]typewhat the memory is used for
[in]max_sizesize of returned memory
Returns
pointer to memory
Return values
NULLno memory available for this min_size and type

◆ wic_rand_fn

typedef uint32_t(* wic_rand_fn) (struct wic_inst *inst)

Called to get a 32bit random number.

Parameters
[in]inst
Returns
random number

◆ wic_on_ping_fn

typedef void(* wic_on_ping_fn) (struct wic_inst *inst)

A ping was received and WIC responded with a pong.

Parameters
[in]inst

◆ wic_on_pong_fn

typedef void(* wic_on_pong_fn) (struct wic_inst *inst)

A pong was received.

Parameters
[in]inst

Enumeration Type Documentation

◆ wic_buffer

enum wic_buffer

this enum is used to communicate the purpose of the buffer

Enumerator
WIC_BUFFER_HTTP 

handshake

WIC_BUFFER_USER 

text or binary

WIC_BUFFER_PING 

ping

WIC_BUFFER_PONG 

pong (in response to ping)

WIC_BUFFER_CLOSE 

close

WIC_BUFFER_CLOSE_RESPONSE 

close (in response to close)

◆ wic_handshake_failure

reason for handshake failure

Enumerator
WIC_HANDSHAKE_FAILURE_ABNORMAL_1 

socket closed for reason WIC_CLOSE_ABNORMAL_1

WIC_HANDSHAKE_FAILURE_ABNORMAL_2 

socket closed for reason WIC_CLOSE_ABNORMAL_2

WIC_HANDSHAKE_FAILURE_TLS 

socket closed for some TLS specific reason

WIC_HANDSHAKE_FAILURE_IRRELEVANT 

another socket close reason not relevant to this mode

WIC_HANDSHAKE_FAILURE_PROTOCOL 

response was not HTTP as expected

WIC_HANDSHAKE_FAILURE_UPGRADE 

response did not upgrade to websocket (e.g.

perhaps it was a redirect)

◆ wic_role

enum wic_role

An instance is either a client or a server.

Enumerator
WIC_ROLE_CLIENT 

Client role.

WIC_ROLE_SERVER 

Server role.

◆ wic_schema

enum wic_schema

URL schema.

◆ wic_state

enum wic_state

WIC instance state.

Enumerator
WIC_STATE_INIT 

initialised

WIC_STATE_PARSE_HANDSHAKE 

parsing http handshake

WIC_STATE_READY 

websocket is ready to start

WIC_STATE_OPEN 

websocket is open

WIC_STATE_CLOSED 

websocket is closed

◆ wic_status

enum wic_status
Enumerator
WIC_STATUS_SUCCESS 

operation complete successfully

WIC_STATUS_NOT_OPEN 

socket is not open

WIC_STATUS_TOO_LARGE 

message too large to send

WIC_STATUS_WOULD_BLOCK 

buffer not available