Application Modules#
This section introduces you to the various network application modules that are included as part of Micrium OS.
Complementary information is also available in the Network section of the Technologies Overview documentation page. The following sections will refer to it when appropriate.
HTTP Client Module#
The Micrium OS HTTP Client can be used to access HTTP servers and perform actions on resources maintained by a server.
In an embedded environment, an HTTP client will rarely be used to display web pages like a web browser does. It will primarily be used to get and update specific data, download and upload files or to interface with web services.
HTTP Client Protocol Recognized Fields
HTTP Client Overview#
Specifications#
Complies with the following RFC:
RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1
RFC 6455 - The WebSocket Protocol
Implements the following methods:
GET
POST
PUT
DELETE
HEAD
Features#
Scalable to contain only required features and minimize memory footprint
Supports persistent connection
Supports form submission
Supports chunked transfer encoding for both reception and transmission
Supports application and multipart forms
Supports reception of HTTP headers in requests and addition of HTTP headers in responses.
Supports HTTP HTTP Query String processing
Supports HTTP WebSocket message processing
Design#
The HTTP Client module has been designed to suit many different types of HTTP client applications. With the right configuration it can be used with a very low footprint to send a simple HTTP request and wait for the HTTP server's response. Another benefit of its design is that it can also be used to make simultaneous HTTP requests by opening multiple connections which allows for consistent usage of the same API calls.
Memory Usage#
Each HTTP client application can have very different memory needs. For example, some applications will only require one connection whereas others will require more; some applications will prefer to allocate objects on their own stack while others will want to use a memory pool on the heap. Therefore, to conform with all of these different requirements, HTTP Client does not have its own memory module. All the objects required by the HTTP Client MUST be passed by the application. Three HTTP Client Objects must be supplied by the Application: a Connection object , a Request Object and a Response Object . Also, a buffer per connection must be supplied for the transmission/reception operations. Additional objects may be required when some available features are enabled.
It is very important that every object passed by the application to the HTTP Client stack remain valid for the duration of the HTTP transaction or until the connection is closed for the HTTP Client Connection Object. |
---|
Internal Task#
To support multiple simultaneous connections, HTTP Client has an internal task. This task also allows the queuing of multiple requests on a given connection. When the HTTP Client Task is present, API calls to HTTP Client's stack can be set to the blocking or non-blocking mode.
For simpler applications and to reduce memory footprint, the internal HTTP Client task can be disabled. In that case, HTTP Client operations will be executed directly in the application task and will always be blocking.
Auto Select Remote IP address#
When the DNS Client that is part of the core network is properly configured, HTTP Client can accept a host name string to connect to the remote server. It will perform the IP address resolution by communicating with a DNS server. If the DNS server sends back IPv4 and IPv6 addresses, the first attempt will be to use the IPv6 address to connect to the remote HTTP server. If this connection fails the IPv4 address will be used instead.
Limitations#
Only supports HTTP v1.1.
HTTP range requests are not supported.
HTTP Client Example Applications#
This section describes the examples that are related to the HTTP Client module of Micrium OS.
HTTP Client Initialization Example#
Description#
This is a generic example that shows how to initialize the HTTP client module. It accomplishes the following tasks:
Initialize the HTTP client module
Create a RAM disk for file exchange:
Store a file (index.html) to be sent to a server
Configuration#
Mandatory#
The following #define must be added in ex_description.h to allow other examples to initialize the HTTP Client module correctly:
#define | Description |
---|---|
EX_HTTP_CLIENT_INIT_AVAIL | Lets the upper example layer know that the HTTP Client Initialization example is present and must be called by other examples. |
Optional#
The following #define can be added to ex_description.h, as described in Example Applications section, to change default configuration value used by the example:
#define | Default value | Description |
---|---|---|
EX_HTTP_CLIENT_RAMDISK_SEC_SIZE | 512 u | Specify the sector size of the RAM disk |
EX_HTTP_CLIENT_RAMDISK_SEC_NBR | 60 u | Specify the number of sector for the RAM disk |
EX_HTTP_CLIENT_FILE_RAM_MEDIA_NAME | "ram_httpc" | Specify the RAM media name |
EX_HTTP_CLIENT_FILE_VOL_NAME | "ram_httpc" | Specify the RAM volume name |
EX_HTTP_CLIENT_WRK_DIR | EX_HTTP_CLIENT_FILE_VOL_NAME | Specify the working directory used by the example |
EX_HTTP_CLIENT_FILE_NAME | "index.html" | Specify the name of the internal file. |
EX_HTTP_CLIENT_CLIENT_HOSTNAME | "httpbin.org" | Specify the server host name used by the client |
EX_HTTP_CLIENT_CONN_NBR_MAX | 5 u | Specify the maximum of active connection |
EX_HTTP_CLIENT_REQ_NBR_MAX | 5 u | Specify the maximum of requests |
EX_HTTP_CLIENT_CONN_BUF_SIZE | 512 u | Specify the connection buffer size |
EX_HTTP_CLIENT_CFG_QUERY_STR_NBR_MAX | 6 u | Specify the maximum number of query string |
EX_HTTP_CLIENT_CFG_QUERY_STR_KEY_LEN_MAX | 20 u | Specify the maximum of query string key length |
EX_HTTP_CLIENT_CFG_QUERY_STR_VAL_LEN_MAX | 50 u | Specify the maximum of query string value length |
EX_HTTP_CLIENT_CFG_HDR_NBR_MAX | 6 u | Specify the maximum of header object |
EX_HTTP_CLIENT_CFG_HDR_VAL_LEN_MAX | 100 u | Specify the maximum of header value length |
EX_HTTP_CLIENT_CFG_FORM_BUF_SIZE | 256 u | Specify the form buffer size. |
EX_HTTP_CLIENT_CFG_FORM_FIELD_NBR_MAX | 10 u | Specify the maximum number of form's field |
EX_HTTP_CLIENT_CFG_FORM_FIELD_KEY_LEN_MAX | 100 u | Specify the maximum of form key length |
EX_HTTP_CLIENT_CFG_FORM_FIELD_VAL_LEN_MAX | 200 u | Specify the maximum of form value length |
EX_HTTP_CLIENT_CFG_FORM_MULTIPART_NAME_LEN_MAX | 100 u | Specify the maximum of multipart name length |
EX_HTTP_CLIENT_CFG_FORM_MULTIPART_FILENAME_LEN_MAX | 100 u | Specify the maximum of multipart filename length |
Location#
/examples/net/http/client/ex_http_client.c
/examples/net/http/client/ex_http_client.h
API#
API | Description |
---|---|
Ex_HTTP_Client_Init() | Initialize the HTTP Client stack for the example application. |
Notes#
None.
HTTP Client GET Request Examples#
Description#
This is a generic example that shows how to send GET request. It accomplishes the following tasks:
Set connection option
Open an HTTP connection
Send GET request
Close HTTP Connection
Configuration#
Optional#
The following #define can be added to ex_description.h, as described in Example Applications section, to change default configuration value used by the example:
#define | Default value | Description |
---|---|---|
EX_HTTP_CLIENT_RAMDISK_SEC_SIZE | 512 u | Specify the sector size of the RAM disk |
EX_HTTP_CLIENT_RAMDISK_SEC_NBR | 60 u | Specify the number of sector for the RAM disk |
EX_HTTP_CLIENT_FILE_RAM_MEDIA_NAME | "ram_httpc" | Specify the RAM media name |
EX_HTTP_CLIENT_FILE_VOL_NAME | "ram_httpc" | Specify the RAM volume name |
EX_HTTP_CLIENT_WRK_DIR | EX_HTTP_CLIENT_FILE_VOL_NAME | Specify the working directory used by the example |
EX_HTTP_CLIENT_FILE_NAME | "index.html" | Specify the name of the internal file. |
EX_HTTP_CLIENT_CLIENT_HOSTNAME | "httpbin.org " | Specify the server host name used by the client |
EX_HTTP_CLIENT_CONN_NBR_MAX | 5 u | Specify the maximum of active connection |
EX_HTTP_CLIENT_REQ_NBR_MAX | 5 u | Specify the maximum of requests |
EX_HTTP_CLIENT_CONN_BUF_SIZE | 512 u | Specify the connection buffer size |
EX_HTTP_CLIENT_CFG_QUERY_STR_NBR_MAX | 6 u | Specify the maximum number of query string |
EX_HTTP_CLIENT_CFG_QUERY_STR_KEY_LEN_MAX | 20 u | Specify the maximum of query string key length |
EX_HTTP_CLIENT_CFG_QUERY_STR_VAL_LEN_MAX | 50 u | Specify the maximum of query string value length |
EX_HTTP_CLIENT_CFG_HDR_NBR_MAX | 6 u | Specify the maximum of header object |
EX_HTTP_CLIENT_CFG_HDR_VAL_LEN_MAX | 100 u | Specify the maximum of header value length |
EX_HTTP_CLIENT_CFG_FORM_BUF_SIZE | 256 u | Specify the form buffer size. |
EX_HTTP_CLIENT_CFG_FORM_FIELD_NBR_MAX | 10 u | Specify the maximum number of form's field |
EX_HTTP_CLIENT_CFG_FORM_FIELD_KEY_LEN_MAX | 100 u | Specify the maximum of form key length |
EX_HTTP_CLIENT_CFG_FORM_FIELD_VAL_LEN_MAX | 200 u | Specify the maximum of form value length |
EX_HTTP_CLIENT_CFG_FORM_MULTIPART_NAME_LEN_MAX | 100 u | Specify the maximum of multipart name length |
EX_HTTP_CLIENT_CFG_FORM_MULTIPART_FILENAME_LEN_MAX | 100 u | Specify the maximum of multipart filename length |
Location#
/examples/net/http/client/ex_http_client_files.c
/examples/net/http/client/ex_http_client_files.h
/examples/net/http/client/ex_http_client_hooks.c
/examples/net/http/client/ex_http_client_hooks.h
/examples/net/http/client/ex_http_client.c
/examples/net/http/client/ex_http_client.h
API#
API | Description |
---|---|
Ex_HTTP_Client_ReqSendGet_NoTask() | Send a GET request synchronously, i.e., returns only when the transaction is completed. |
Ex_HTTP_Client_ReqSendGet() | Send a GET request asynchronously. Show the callback system to be notified when the transaction is completed. |
Notes#
None.
HTTP Client POST Request Examples#
Description#
This is a generic example that shows how to send POST request. It accomplishes the following tasks:
Set connection option
Open an HTTP connection
Send POST request
Close HTTP Connection
Configuration#
Optional#
The following #define can be added to ex_description.h, as described in Example Applications section, to change default configuration value used by the example:
#define | Default value | Description |
---|---|---|
EX_HTTP_CLIENT_RAMDISK_SEC_SIZE | 512 u | Specify the sector size of the RAM disk |
EX_HTTP_CLIENT_RAMDISK_SEC_NBR | 60 u | Specify the number of sector for the RAM disk |
EX_HTTP_CLIENT_FILE_RAM_MEDIA_NAME | "ram_httpc" | Specify the RAM media name |
EX_HTTP_CLIENT_FILE_VOL_NAME | "ram_httpc" | Specify the RAM volume name |
EX_HTTP_CLIENT_WRK_DIR | EX_HTTP_CLIENT_FILE_VOL_NAME | Specify the working directory used by the example |
EX_HTTP_CLIENT_FILE_NAME | "index.html" | Specify the name of the internal file. |
EX_HTTP_CLIENT_CLIENT_HOSTNAME | "httpbin.org " | Specify the server host name used by the client |
EX_HTTP_CLIENT_CONN_NBR_MAX | 5 u | Specify the maximum of active connection |
EX_HTTP_CLIENT_REQ_NBR_MAX | 5 u | Specify the maximum of requests |
EX_HTTP_CLIENT_CONN_BUF_SIZE | 512 u | Specify the connection buffer size |
EX_HTTP_CLIENT_CFG_QUERY_STR_NBR_MAX | 6 u | Specify the maximum number of query string |
EX_HTTP_CLIENT_CFG_QUERY_STR_KEY_LEN_MAX | 20 u | Specify the maximum of query string key length |
EX_HTTP_CLIENT_CFG_QUERY_STR_VAL_LEN_MAX | 50 u | Specify the maximum of query string value length |
EX_HTTP_CLIENT_CFG_HDR_NBR_MAX | 6 u | Specify the maximum of header object |
EX_HTTP_CLIENT_CFG_HDR_VAL_LEN_MAX | 100 u | Specify the maximum of header value length |
EX_HTTP_CLIENT_CFG_FORM_BUF_SIZE | 256 u | Specify the form buffer size. |
EX_HTTP_CLIENT_CFG_FORM_FIELD_NBR_MAX | 10 u | Specify the maximum number of form's field |
EX_HTTP_CLIENT_CFG_FORM_FIELD_KEY_LEN_MAX | 100 u | Specify the maximum of form key length |
EX_HTTP_CLIENT_CFG_FORM_FIELD_VAL_LEN_MAX | 200 u | Specify the maximum of form value length |
EX_HTTP_CLIENT_CFG_FORM_MULTIPART_NAME_LEN_MAX | 100 u | Specify the maximum of multipart name length |
EX_HTTP_CLIENT_CFG_FORM_MULTIPART_FILENAME_LEN_MAX | 100 u | Specify the maximum of multipart filename length |
Location#
/examples/net/http/client/ex_http_client_files.c
/examples/net/http/client/ex_http_client_files.h
/examples/net/http/client/ex_http_client_hooks.c
/examples/net/http/client/ex_http_client_hooks.h
/examples/net/http/client/ex_http_client.c
/examples/net/http/client/ex_http_client.h
API#
API | Description |
---|---|
Ex_HTTP_Client_ReqSendPost() | Send a POST request with a pre-formatted form as body. |
Ex_HTTP_Client_ReqSendAppForm() | Send an Application type form. |
Ex_HTTP_Client_ReqSendMultipartForm() | Send a multipart type form. |
Notes#
None.
HTTP Client PUT Request Examples#
Description#
This is a generic example that shows how to send PUT request. It accomplishes the following tasks:
Set connection option
Open an HTTP connection
Send PUT request
Close HTTP Connection
Configuration#
Optional#
The following #define can be added to ex_description.h, as described in Example Applications section, to change default configuration value used by the example:
#define | Default value | Description |
---|---|---|
EX_HTTP_CLIENT_RAMDISK_SEC_SIZE | 512 u | Specify the sector size of the RAM disk |
EX_HTTP_CLIENT_RAMDISK_SEC_NBR | 60 u | Specify the number of sector for the RAM disk |
EX_HTTP_CLIENT_FILE_RAM_MEDIA_NAME | "ram_httpc" | Specify the RAM media name |
EX_HTTP_CLIENT_FILE_VOL_NAME | "ram_httpc" | Specify the RAM volume name |
EX_HTTP_CLIENT_WRK_DIR | EX_HTTP_CLIENT_FILE_VOL_NAME | Specify the working directory used by the example |
EX_HTTP_CLIENT_FILE_NAME | "index.html" | Specify the name of the internal file. |
EX_HTTP_CLIENT_CLIENT_HOSTNAME | "httpbin.org " | Specify the server host name used by the client |
EX_HTTP_CLIENT_CONN_NBR_MAX | 5 u | Specify the maximum of active connection |
EX_HTTP_CLIENT_REQ_NBR_MAX | 5 u | Specify the maximum of requests |
EX_HTTP_CLIENT_CONN_BUF_SIZE | 512 u | Specify the connection buffer size |
EX_HTTP_CLIENT_CFG_QUERY_STR_NBR_MAX | 6 u | Specify the maximum number of query string |
EX_HTTP_CLIENT_CFG_QUERY_STR_KEY_LEN_MAX | 20 u | Specify the maximum of query string key length |
EX_HTTP_CLIENT_CFG_QUERY_STR_VAL_LEN_MAX | 50 u | Specify the maximum of query string value length |
EX_HTTP_CLIENT_CFG_HDR_NBR_MAX | 6 u | Specify the maximum of header object |
EX_HTTP_CLIENT_CFG_HDR_VAL_LEN_MAX | 100 u | Specify the maximum of header value length |
EX_HTTP_CLIENT_CFG_FORM_BUF_SIZE | 256 u | Specify the form buffer size. |
EX_HTTP_CLIENT_CFG_FORM_FIELD_NBR_MAX | 10 u | Specify the maximum number of form's field |
EX_HTTP_CLIENT_CFG_FORM_FIELD_KEY_LEN_MAX | 100 u | Specify the maximum of form key length |
EX_HTTP_CLIENT_CFG_FORM_FIELD_VAL_LEN_MAX | 200 u | Specify the maximum of form value length |
EX_HTTP_CLIENT_CFG_FORM_MULTIPART_NAME_LEN_MAX | 100 u | Specify the maximum of multipart name length |
EX_HTTP_CLIENT_CFG_FORM_MULTIPART_FILENAME_LEN_MAX | 100 u | Specify the maximum of multipart filename length |
Location#
/examples/net/http/client/ex_http_client_files.c
/examples/net/http/client/ex_http_client_files.h
/examples/net/http/client/ex_http_client_hooks.c
/examples/net/http/client/ex_http_client_hooks.h
/examples/net/http/client/ex_http_client.c
/examples/net/http/client/ex_http_client.h
API#
API | Description |
---|---|
Ex_HTTP_Client_ReqSendPut() | Send PUT request. |
Notes#
None.
HTTP Client Persistent Connection Examples#
Description#
This is a generic example that shows how to send multiple GET request on the same connection. It accomplishes the following tasks:
Set connection option
Open an HTTP connection
Send GET request #1
Send GET request #2
Close HTTP Connection
Configuration#
Optional#
The following #define can be added to ex_description.h, as described in Example Applications section, to change default configuration value used by the example:
#define | Default value | Description |
---|---|---|
EX_HTTP_CLIENT_RAMDISK_SEC_SIZE | 512 u | Specify the sector size of the RAM disk |
EX_HTTP_CLIENT_RAMDISK_SEC_NBR | 60 u | Specify the number of sector for the RAM disk |
EX_HTTP_CLIENT_FILE_RAM_MEDIA_NAME | "ram_httpc" | Specify the RAM media name |
EX_HTTP_CLIENT_FILE_VOL_NAME | "ram_httpc" | Specify the RAM volume name |
EX_HTTP_CLIENT_WRK_DIR | EX_HTTP_CLIENT_FILE_VOL_NAME | Specify the working directory used by the example |
EX_HTTP_CLIENT_FILE_NAME | "index.html" | Specify the name of the internal file. |
EX_HTTP_CLIENT_CLIENT_HOSTNAME | "httpbin.org " | Specify the server host name used by the client |
EX_HTTP_CLIENT_CONN_NBR_MAX | 5 u | Specify the maximum of active connection |
EX_HTTP_CLIENT_REQ_NBR_MAX | 5 u | Specify the maximum of requests |
EX_HTTP_CLIENT_CONN_BUF_SIZE | 512 u | Specify the connection buffer size |
EX_HTTP_CLIENT_CFG_QUERY_STR_NBR_MAX | 6 u | Specify the maximum number of query string |
EX_HTTP_CLIENT_CFG_QUERY_STR_KEY_LEN_MAX | 20 u | Specify the maximum of query string key length |
EX_HTTP_CLIENT_CFG_QUERY_STR_VAL_LEN_MAX | 50 u | Specify the maximum of query string value length |
EX_HTTP_CLIENT_CFG_HDR_NBR_MAX | 6 u | Specify the maximum of header object |
EX_HTTP_CLIENT_CFG_HDR_VAL_LEN_MAX | 100 u | Specify the maximum of header value length |
EX_HTTP_CLIENT_CFG_FORM_BUF_SIZE | 256 u | Specify the form buffer size. |
EX_HTTP_CLIENT_CFG_FORM_FIELD_NBR_MAX | 10 u | Specify the maximum number of form's field |
EX_HTTP_CLIENT_CFG_FORM_FIELD_KEY_LEN_MAX | 100 u | Specify the maximum of form key length |
EX_HTTP_CLIENT_CFG_FORM_FIELD_VAL_LEN_MAX | 200 u | Specify the maximum of form value length |
EX_HTTP_CLIENT_CFG_FORM_MULTIPART_NAME_LEN_MAX | 100 u | Specify the maximum of multipart name length |
EX_HTTP_CLIENT_CFG_FORM_MULTIPART_FILENAME_LEN_MAX | 100 u | Specify the maximum of multipart filename length |
Location#
/examples/net/http/client/ex_http_client_files.c
/examples/net/http/client/ex_http_client_files.h
/examples/net/http/client/ex_http_client_hooks.c
/examples/net/http/client/ex_http_client_hooks.h
/examples/net/http/client/ex_http_client.c
/examples/net/http/client/ex_http_client.h
API#
API | Description |
---|---|
Ex_HTTP_Client_PersistentConn() | Send multiple requests on same connection. |
Notes#
None.
HTTP Client Multi-connection Examples#
Description#
This is a generic example that shows how to open multiple connections and how to send requests in parallel. It accomplishes the following tasks:
Set connection #1 option
Set connection #2 option
Open an HTTP connection #1
Open an HTTP connection #2
Send GET request #1
Send GET request #2
Configuration#
Optional#
The following #define can be added to ex_description.h, as described in Example Applications section, to change default configuration value used by the example:
#define | Default value | Description |
---|---|---|
EX_HTTP_CLIENT_RAMDISK_SEC_SIZE | 512 u | Specify the sector size of the RAM disk |
EX_HTTP_CLIENT_RAMDISK_SEC_NBR | 60 u | Specify the number of sector for the RAM disk |
EX_HTTP_CLIENT_FILE_RAM_MEDIA_NAME | "ram_httpc" | Specify the RAM media name |
EX_HTTP_CLIENT_FILE_VOL_NAME | "ram_httpc" | Specify the RAM volume name |
EX_HTTP_CLIENT_WRK_DIR | EX_HTTP_CLIENT_FILE_VOL_NAME | Specify the working directory used by the example |
EX_HTTP_CLIENT_FILE_NAME | "index.html" | Specify the name of the internal file. |
EX_HTTP_CLIENT_CLIENT_HOSTNAME | "httpbin.org " | Specify the server host name used by the client |
EX_HTTP_CLIENT_CONN_NBR_MAX | 5 u | Specify the maximum of active connection |
EX_HTTP_CLIENT_REQ_NBR_MAX | 5 u | Specify the maximum of requests |
EX_HTTP_CLIENT_CONN_BUF_SIZE | 512 u | Specify the connection buffer size |
EX_HTTP_CLIENT_CFG_QUERY_STR_NBR_MAX | 6 u | Specify the maximum number of query string |
EX_HTTP_CLIENT_CFG_QUERY_STR_KEY_LEN_MAX | 20 u | Specify the maximum of query string key length |
EX_HTTP_CLIENT_CFG_QUERY_STR_VAL_LEN_MAX | 50 u | Specify the maximum of query string value length |
EX_HTTP_CLIENT_CFG_HDR_NBR_MAX | 6 u | Specify the maximum of header object |
EX_HTTP_CLIENT_CFG_HDR_VAL_LEN_MAX | 100 u | Specify the maximum of header value length |
EX_HTTP_CLIENT_CFG_FORM_BUF_SIZE | 256 u | Specify the form buffer size. |
EX_HTTP_CLIENT_CFG_FORM_FIELD_NBR_MAX | 10 u | Specify the maximum number of form's field |
EX_HTTP_CLIENT_CFG_FORM_FIELD_KEY_LEN_MAX | 100 u | Specify the maximum of form key length |
EX_HTTP_CLIENT_CFG_FORM_FIELD_VAL_LEN_MAX | 200 u | Specify the maximum of form value length |
EX_HTTP_CLIENT_CFG_FORM_MULTIPART_NAME_LEN_MAX | 100 u | Specify the maximum of multipart name length |
EX_HTTP_CLIENT_CFG_FORM_MULTIPART_FILENAME_LEN_MAX | 100 u | Specify the maximum of multipart filename length |
Location#
/examples/net/http/client/ex_http_client_files.c
/examples/net/http/client/ex_http_client_files.h
/examples/net/http/client/ex_http_client_hooks.c
/examples/net/http/client/ex_http_client_hooks.h
/examples/net/http/client/ex_http_client.c
/examples/net/http/client/ex_http_client.h
API#
API | Description |
---|---|
Ex_HTTP_Client_MultiConn() | Open multiple Connections to send HTTP requests in parallel. |
Notes#
None.
HTTP Client Configuration#
In order to address your application's needs, the HTTP Client module must be properly configured. There are two groups of configuration parameters:
HTTP Client Compile-Time Configurations#
Micrium OS HTTP Client is configurable at compile time via several #defines located in http_client_cfg.h file. HTTP Client module uses #defines when possible, because they allow code and data sizes to be scaled at compile time based on enabled features. This allows the Read-Only Memory (ROM) and Random-Access Memory (RAM) footprints of the HTTP Client module to be adjusted based on application requirements.
It is recommended that the configuration process begins with the default configuration values which in the next sections will be shown in bold.
Task Configuration#
HTTP Client module has an internal task that can be enabled or disabled. Using this internal task allows for simultaneous connection processing and using the API in a non-blocking mode.
Table - HTTPc Task Configuration#
Constant | Description | Possible Values |
---|---|---|
HTTPc_CFG_MODE_ASYNC_TASK_EN | Enables/Disables the internal asynchronous task.When ENABLED, the internal task can accept simultaneous connections and can queue requests. API functions can be called with the non-blocking flag.When DISABLED, the API functions will always be blocking. | DEF_ENABLED or DEF_DISABLED |
HTTPc_CFG_MODE_BLOCK_EN | Enables/Disables the blocking option when the internal task is active.When the internal task is enabled, API functions can also be blocking but only if this configuration is enabled. | DEF_ENABLED or DEF_DISABLED |
Persistent Connection Configuration#
Table - HTTPc Persistent Connection Configuration#
Constant | Description | Possible Values |
---|---|---|
HTTPc_CFG_PERSISTENT_EN | Enables/Disables the Persistent Connection Feature. | DEF_ENABLED or DEF_DISABLED |
Chunked Transfer Encoding Configuration#
Table - HTTPc Chunked Transfer Encoding Configuration#
Constant | Description | Possible Values |
---|---|---|
HTTPc_CFG_CHUNK_TX_EN | Enables/Disables the Chunked Transfer Encoding feature for transmission | DEF_ENABLED or DEF_DISABLED |
Query String Configuration#
Table - HTTPc Query String Configuration#
Constant | Description | Possible Values |
---|---|---|
HTTPc_CFG_QUERY_STR_EN | Enables/Disables the Query String Feature. | DEF_ENABLED or DEF_DISABLED |
Header Field Configuration#
Table - HTTPc Header Field Configuration#
Constant | Description | Possible Values |
---|---|---|
HTTPc_CFG_HDR_RX_EN | Enables/Disables the addition of header fields to HTTP Requests when transmitting. | DEF_ENABLED or DEF_DISABLED |
HTTPc_CFG_HDR_TX_EN | Enables/Disables the copy and processing of header fields for HTTP Responses received. | DEF_ENABLED or DEF_DISABLED |
Form Submission Configuration#
Table - HTTPc Form Submission Configuration#
Constant | Description | Possible Values |
---|---|---|
HTTPc_CFG_FORM_EN | Enables/Disables the HTTP Form Submission Feature. | DEF_ENABLED or DEF_DISABLED |
User Data Configuration#
Table - HTTPc User Data Configuration#
Constant | Description | Possible Values |
---|---|---|
HTTPc_CFG_USER_DATA_EN | Enables/Disables the addition of a void pointer in the HTTPc_CONN_OBJ and HTTPc_REQ_OBJ objects.The additional void pointer can be used by the upper application to store an application data pointer relative to the object. | DEF_ENABLED or DEF_DISABLED |
WebSocket Configuration#
Table - HTTPc WebSocket Configuration#
Constant | Description | Possible Values |
---|---|---|
HTTPc_CFG_WEBSOCKET_EN | Enables/Disables the WebSocket Feature. | DEF_ENABLED or DEF_DISABLED |
The WebSocket feature requires HTTPc_CFG_MODE_ASYNC_TASK_EN to be set to DEF_ENABLED. |
---|
HTTP Client Run-Time Application Specific Configurations#
This section defines the configurations related to HTTP Client but that are specified at run-time, during the initialization process.
Initialization#
Initializing the HTTP Client module is done by calling the function HTTPc_Init(). This function takes no configuration argument. Unless you override an optional configuration before calling the function HTTPc_Init(), the default configurations will be used.
Optional configurations#
This section describes the configurations that are optional. If you do not set them in your application, the default configurations will apply.
The default values can be retrieved via the structure HTTPc_InitCfgDflt.
Note that these configurations must be set before you call the function HTTPc_Init(). |
---|
Table - HTTP Client Optional Configurations#
Configurations | Description | Type | Function to call | Default | Field from default configuration structure |
---|---|---|---|---|---|
Task's stack | The HTTP client module can use a task depending on the compile-time configuration. This configuration allows you to set the stack pointer and the stack size (in quantity of elements). | CPU_INT32Uvoid * | HTTPc_ConfigureTaskStk() | A stack of 768 elements allocated on Common 's memory segment. | .StkSizeElements.StkPtr |
Memory segment | This module allocates some control data. You can specify the memory segment from where such data should be allocated. | MEM_SEG * | HTTPc_ConfigureMemSeg() | .MemSegPtr | |
Quantity parameters | The HTTP client task use a message queue. You can overwrite the maximum element in the message pool. | HTTPc_QTY_CFG | HTTPc_ConfigureQty() | Unlimited queue size. | .QtyCfg |
Connection parameters | The HTTP client allows to configure the connection timeouts. | HTTPc_CONN_CFG | HTTPc_ConfigureConnParam() | Timeout of 30 milliseconds for connection timeout and 30 seconds for inactivity. | .ConnCfg |
Post-Init Configurations#
This section describes the configurations that can be set at any time during execution after you called the function HTTPc_Init().
These configurations are optional. If you do not set them in your application, the default configurations will apply.
Table - HTTP Client Post-init Configurations#
Configurations | Description | Type | Function to call | Default |
---|---|---|---|---|
Task priority | The HTTP client module will create a task that handles the HTTP requests. You can change the priority of the created task at any time. | RTOS_TASK_PRIO | HTTPc_TaskPrioSet() | |
Task Delay | If the HTTP client module uses a task, you can change the delay inside this task to allow a period of time for other tasks to run. | CPU_INT08U | HTTPc_TaskDlySet() | 1u |
HTTP Client Connection Configurations#
Table - HTTPc_CONN_CFG configuration structure in the HTTP Client Connection Configurations page describes each configuration field available in this configuration structure.
Table - HTTPc_CONN_CFG configuration structure#
Field | Description |
---|---|
.ConnConnectTimeout_ms | Connection connect timeout, in milliseconds. |
.ConnInactivityTimeout_s | Connection inactivity timeout, in seconds. |
HTTP Client Quantity Configurations#
Table - HTTPc_QTY_CFG configuration structure in the HTTP Client Quantity Configurations page describes each configuration field available in this configuration structure.
Table - HTTPc_QTY_CFG configuration structure#
Field | Description |
---|---|
.MsgQ_Size | Maximum size of the message queue. |
HTTP Client Programming Guide#
This Section regroups topics to help developing a custom HTTP client application with the MIcrium OS HTTP Client module. Examples are include in many sub-sections.
HTTP Client Control Structure#
The HTTP Client module offers many structures that the application can use to create objects to interact with the API.
All the HTTP Client Objects required by the application must be allocated by the application and passed to the HTTP Client API.
All objects or strings passed to the HTTP Client API MUST be persistent and unmodified for the duration of the HTTP Transaction for Request-oriented parameters and objects; or until the HTTP connection is closed for Connection-oriented parameters and objects. |
---|
HTTP Client Connection (HTTPc_CONN_OBJ)#
This structure is the main one used by the HTTP Client module. It contains all parameters relative to an HTTP connection (server port number, server address, server host name, etc.) and also many internal parameters for the HTTP connection and HTTP transaction processing.
Each configurable parameter SHOULD be set up with the function HTTPc_ConnSetParam(). The list of available parameters for a connection can be viewed here .
The members of an HTTP Client object should never be directly tampered with at any time. To ensure this, the HTTPc_CONN_OBJ structure's members have all been declared constant with the const keyword and the suffix _reserved has been added.
Listing - HTTPc_CONN Structure#
struct httpc_conn_obj {
/* --------- CONNECTION PARAMETERS --------- */
const NET_SOCK_ID SockID_reserved; /* Connection's Socket ID. */
const HTTPc_FLAGS SockFlags_reserved; /* Connection's Socket flags. */
#ifdef NET_SECURE_MODULE_EN
const NET_APP_SOCK_SECURE_CFG SockSecureCfg_reserved; /* Connection's Socket Secure Cfg. */
#endif
const CPU_INT16U ConnectTimeout_ms_reserved; /* Connection Connect Timeout. */
const CPU_INT16U InactivityTimeout_s_reserved; /* Connection Inactivity Timeout. */
const NET_PORT_NBR ServerPort_reserved;
const NET_SOCK_ADDR ServerSockAddr_reserved; /* Server socket address. */
const CPU_CHAR *HostNamePtr_reserved; /* Pointer to HTTP server hostname string. */
const CPU_INT16U HostNameLen_reserved;
const HTTPc_CONN_STATE State_reserved; /* Connection State. */
const HTTPc_FLAGS Flags_reserved; /* Set of flags related to HTTP connection. */
const HTTPc_CONN_CLOSE_STATUS CloseStatus_reserved; /* Status of connection closed. */
const HTTPc_ERR ErrCode_reserved; /* Error code of connection. */
#ifdef HTTPc_TASK_MODULE_EN
const HTTPc_CONNECT_CALLBACK OnConnect_reserved; /* Connection Connect callback function. */
const HTTPc_CONN_CLOSE_CALLBACK OnClose_reserved; /* Connection Close callback function. */
const HTTPc_CONN_ERR_CALLBACK OnErr_reserved; /* Connection Error callback function. */
#endif
#ifdef HTTPc_SIGNAL_TASK_MODULE_EN
const KAL_SEM_HANDLE ConnectSignal_reserved; /* HTTP Socket Connect Done Signal. */
const KAL_SEM_HANDLE TransDoneSignal_reserved; /* HTTP Transaction Done Signal. */
const KAL_SEM_HANDLE CloseSignal_reserved; /* HTTP Socket Close Done Signal. */
#endif
/* ----------- REQUEST PARAMETERS ---------- */
const HTTPc_REQ *ReqListHeadPtr_reserved; /* Head of the Request list. */
const HTTPc_REQ *ReqListEndPtr_reserved; /* End of the Request list. */
const HTTPc_FLAGS ReqFlags_reserved; /* Set of flags related to the HTTP request. */
#if (HTTPc_CFG_QUERY_STR_EN == DEF_ENABLED)
const CPU_INT16U ReqQueryStrTxIx_reserved; /* Tbl index of the transmitted strings. */
const HTTPc_KEY_VAL *ReqQueryStrTempPtr_reserved; /* Temporary Query String to Tx. */
#endif
#if (HTTPc_CFG_HDR_TX_EN == DEF_ENABLED)
const CPU_INT08U ReqHdrTxIx_reserved; /* Index in Req hdr table to Tx headers. */
const HTTP_HDR *ReqHdrTempPtr_reserved; /* Temporary Header field to Tx. */
#endif
#if (HTTPc_CFG_FORM_EN == DEF_ENABLED)
const CPU_INT16U ReqFormDataTxIx_reserved; /* Index in form table to Tx form fields. */
#endif
const CPU_INT16U ReqDataOffset_reserved; /* Offset in Request Data Pointer to Tx data */
/* ----------- RESPONSE PARAMETERS --------- */
const HTTPc_FLAGS RespFlags_reserved; /* Set of flags related to the HTTP response.*/
/* ------ CONNECTION BUFFER PARAMETERS ----- */
const void *TxDataPtr_reserved; /* Pointer to data to transmit. */
const CPU_CHAR *BufPtr_reserved; /* Pointer to conn buffer. */
const CPU_INT16U BufLen_reserved; /* Conn buffer length. */
const CPU_CHAR *RxBufPtr_reserved; /* Pointer to Buffer where to Rx data. */
const CPU_INT16U RxDataLenRem_reserved; /* Remaining data in the RX buffer. */
const CPU_INT32U RxDataLen_reserved; /* Data length received. */
const CPU_CHAR *TxBufPtr_reserved; /* Pointer to Buffer where to Tx data. */
const CPU_INT16U TxDataLen_reserved; /* Length of data to Tx. */
/* ------- CONNECTION LIST PARAMETERS ------ */
const HTTPc_CONN *NextPtr_reserved; /* Pointer to next connection. */
#if (HTTPc_CFG_USER_DATA_EN == DEF_ENABLED)
/* ---------- USER DATA PARAMETER ---------- */
void *UserDataPtr;
#endif
};
HTTP Client Request (HTTPc_REQ_OBJ)#
This structure regroups parameters and flags related to the configuration of an HTTP request.
Each configurable parameter SHOULD be set up with the function HTTPc_ReqSetParam(). The list of available parameters for a connection can be viewed here .
The members of an HTTP Request object should never be directly tempered with at any time. To ensure this, the HTTPc_REQ_OBJ structure's members have all been declared constant with the const keyword and the suffix _reserved has been added.
Listing - HTTPc_REQ Structure#
struct httpc_req_obj {
const HTTPc_FLAGS Flags_reserved;
const HTTPc_FLAGS HdrFlags_reserved;
const HTTP_METHOD Method_reserved;
const CPU_CHAR *ResourcePathPtr_reserved;
const CPU_INT16U ResourcePathLen_reserved;
const HTTP_CONTENT_TYPE ContentType_reserved;
const CPU_INT32U ContentLen_reserved;
const void *DataPtr_reserved;
#if (HTTPc_CFG_QUERY_STR_EN == DEF_ENABLED)
const HTTPc_KEY_VAL *QueryStrTbl_reserved;
const CPU_INT16U QueryStrNbr_reserved;
const HTTPc_REQ_QUERY_STR_HOOK OnQueryStrTx_reserved;
#endif
#if (HTTPc_CFG_HDR_TX_EN == DEF_ENABLED)
const HTTP_HDR *HdrTbl_reserved;
const CPU_INT16U HdrNbr_reserved;
const HTTPc_REQ_HDR_HOOK OnHdrTx_reserved;
#endif
#if (HTTPc_CFG_FORM_EN == DEF_ENABLED)
const HTTPc_FORM_TBL_FIELD *FormFieldTbl_reserved;
const CPU_INT16U FormFieldNbr_reserved;
#endif
#if (HTTPc_CFG_CHUNK_TX_EN == DEF_ENABLED)
const HTTPc_REQ_BODY_HOOK OnBodyChunkTx_reserved;
#endif
#if (HTTPc_CFG_HDR_RX_EN == DEF_ENABLED)
const HTTPc_RESP_HDR_HOOK OnHdrRx_reserved; /* Resp Hdr Hook fnct to choose which hdr to keep*/
#endif
const HTTPc_RESP_BODY_HOOK OnBodyRx_reserved; /* Resp Body Hook fnct to pass Rx data to app. */
#ifdef HTTPc_TASK_MODULE_EN
const HTTPc_COMPLETE_CALLBACK OnTransComplete_reserved; /* Response received callback function. */
const HTTPc_TRANS_ERR_CALLBACK OnErr_reserved; /* Transaction Error callback function. */
#endif
const HTTPc_CONN *ConnPtr_reserved; /* Pointer to Connection Object. */
const HTTPc_RESP *RespPtr_reserved; /* Pointer to Conn Response Object. */
const HTTPc_REQ *NextPtr_reserved;
#if (HTTPc_CFG_USER_DATA_EN == DEF_ENABLED)
void *UserDataPtr;
#endif
};
HTTP Client Response (HTTPc_RESP_OBJ)#
This structure will be filled by the HTTP Client core with the data received in the HTTP response; except for the body part that is retrieved by the application with the hook function On Response Body .
Listing - HTTPc_RESP Structure#
struct httpc_resp_obj {
HTTP_PROTOCOL_VER ProtocolVer; /* HTTP version received in response message. */
HTTP_STATUS_CODE StatusCode; /* Status code received in response. */
const CPU_CHAR *ReasonPhrasePtr; /* Pointer to received reason phrase. */
HTTP_CONTENT_TYPE ContentType; /* Content type received in response. */
CPU_INT32U ContentLen; /* Content length received in response if any. */
}
HTTP Client Key-Value Pair (HTTPc_KEY_VAL)#
Key-Value Pair Objects can be used with the HTTP Query String feature and the HTTP Form feature.
The structure's object allows for storing the pointer to an application's Key string and the pointer to its Value string's equivalent key. The string's length must also be saved in the object.
Listing - HTTPc_KEY_VAL Structure#
struct httpc_key_val {
CPU_CHAR *KeyPtr; /* Pointer to Key String. */
CPU_INT16U KeyLen; /* Length of Key String. */
CPU_CHAR *ValPtr; /* Pointer to Value String. */
CPU_INT16U ValLen; /* Length of Value String. */
};
HTTP Client Extended Key-Value Pair (HTTPc_KEY_VAL_EXT)#
Extended Key-Value Pair Objects can be used with the HTTP Form feature. More specifically, with a multipart type form.
Extended Key-Value Pair Objects are very similar to the Key-Value Pair Objects except that the value pointer is replaced by a hook function that will allow the application to directly copy the value into the HTTP Client buffer.
Listing - HTTPc_KEY_VAL_EXT Structure#
struct httpc_key_val_ext {
CPU_CHAR *KeyPtr; /* Pointer to Key String. */
CPU_INT16U KeyLen; /* Length of Key String. */
HTTPc_KEY_VAL_EXT_HOOK OnValTx; /* Pointer to Hook Function to set Value. */
CPU_INT32U ValLen; /* Length of the Value String. */
};
HTTP Client Multipart File (HTTPc_MULTIPART_FILE)#
Multipart File Objects can be used with the HTTP Form feature. More specifically, with a multipart type form.
The structure's object allows it to store a pointer to the strings file name, the HTTP Content Type of the file and the hook function pointer that will be used to read the file into the transmit buffer.
Listing - HTTPc_MULTIPART_FILE Structure#
struct http_multipart_file {
CPU_CHAR *NamePtr; /* Pointer to Name of form field. */
CPU_INT16U NameLen; /* Length of the form field's name. */
CPU_CHAR *FileNamePtr; /* Pointer to File Name String. */
CPU_INT16U FileNameLen; /* Length of the File Name String. */
CPU_INT32U FileLen; /* File Length. */
HTTP_CONTENT_TYPE ContentType; /* HTTP Content Type of the file. */
HTTPc_MULTIPART_FILE_HOOK OnFileTx; /* Pointer to Hook Function to Transmit file's data. */
};
HTTP Client Header (HTTPc_HDR)#
This structure is used by the application to add Header Fields to an HTTP request.
Listing - HTTP_HDR Structure#
struct httpc_hdr {
HTTP_HDR_FIELD HdrField; /* HTTP Header Field Type. */
CPU_CHAR *ValPtr; /* Pointer to Header Field Value. */
CPU_INT16U ValLen; /* Length of the value. */
};
HTTP Client Connection Object Setup#
Connection's Parameters#
HTTP Client provides the function HTTPc_ConnSetParam() to configure parameters related to the HTTP Client Connection object . The function takes as argument the type of parameter and the pointer to the parameter. The below parameter's types are available:
Table - HTTPc Connection's Parameters#
Parameter Type | Description |
---|---|
HTTPc_PARAM_TYPE_SERVER_PORT | Sets a specific port for the remote HTTP server.By default, the port is set to 80 or to 443 when the Secure module is used. |
HTTPc_PARAM_TYPE_PERSISTENT | Enables the persistent connection mode.The HTTP client will not close the connection at the end of a transaction and will also notify the HTTP server to do the same. The HTTP server must also support persistent connections for the mode to be functional. Enabling this feature on the HTTP client is no guaranty that a persistent connection with the server will be established but that a best effort will be made. |
HTTPc_PARAM_TYPE_CONNECT_TIMEOUT | Sets the Connect Timeout of the connection.This value represents the time allowed for the connection process to complete. |
HTTPc_PARAM_TYPE_INACTIVITY_TIMEOUT | Sets the Inactivity Timeout of the connectionThis value represents the time of inactivity allowed on a connection before it is automatically closed. |
HTTPc_PARAM_TYPE_SECURE_COMMON_NAME | Sets the Common Name linked to the HTTP server's SSL Certificate.The Common Name is associated with the SSL Certificate of a web server. The host + domain name is commonly used for the Common Name, ex: "www.example.com " or "example.com ". When the HTTP client attempts a secure connection, by default the host name will be used as Common Name. You can use this parameter to specify a different Common Name for a secure connection. |
HTTPc_PARAM_TYPE_SECURE_TRUST_CALLBACK | Sets the callback function to notify the application when a secure connection with a server was made to ensure that server certificate is trustworthy.This parameter is mandatory if a secure connection to the server is desired. Therefore, when this parameter is set up, the connection with the server will be automatically a secure one. |
HTTPc_PARAM_TYPE_CONN_CONNECT_CALLBACK | Sets the callback function to notify the application when a connection attempt with the HTTP server is completed.This parameter is mandatory when the HTTPc_CFG_MODE_ASYNC_TASK_EN configuration is enabled and when the function HTTPc_ConnOpen() is called in the none-blocking mode. |
HTTPc_PARAM_TYPE_CONN_CLOSE_CALLBACK | Sets the callback function to notify the application when an HTTP connection was closed.A connection can be closed at any moment by the HTTP server, or by the client when an unexpected error occurred. A connection will also be closed after any transaction when the persistent mode is not enabled.This parameter is mandatory when the HTTPc_CFG_MODE_ASYNC_TASK_EN configuration is enabled. |
Example#
Listing - HTTP Client Connection#
CPU_BOOLEAN HTTPcApp_ConnPrepare (HTTPc_CONN_OBJ *p_conn)
{
CPU_BOOLEAN persistent;
RTOS_ERR err;
/* ---------------- INIT NEW CONNECTION --------------- */
HTTPc_ConnClr(p_conn, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ----------------- SET SERVER PORT ------------------ */
port = 8080;
HTTPc_ConnSetParam(p_conn,
HTTPc_PARAM_TYPE_SERVER_PORT,
&port,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* --------------- SET PERSISTENT MODE ---------------- */
persistent = DEF_YES;
HTTPc_ConnSetParam(p_conn,
HTTPc_PARAM_TYPE_PERSISTENT,
&persistent,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* --------------- SET CONN'S CALLBACKS --------------- */
#if (HTTPc_CFG_MODE_ASYNC_TASK_EN == DEF_ENABLED)
HTTPc_ConnSetParam(p_conn,
HTTPc_PARAM_TYPE_CONN_CONNECT_CALLBACK,
&AppHTTPc_ConnConnectCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
HTTPc_ConnSetParam(p_conn,
HTTPc_PARAM_TYPE_CONN_CLOSE_CALLBACK,
&AppHTTPc_ConnCloseCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
#endif
return (DEF_OK);
}
HTTP Client Request Object Setup#
Request's Parameters#
HTTP Client provides the function HTTPc_ReqSetParam() to configure parameters related to the HTTP Request. The function takes as argument the type of parameter and the pointer to the parameter. The below parameter's types are available:
Table - HTTPc Request's Parameters#
Parameter Type | Description |
---|---|
HTTPc_PARAM_TYPE_REQ_QUERY_STR_TBL | Sets the Request's Query String Table. |
HTTPc_PARAM_TYPE_REQ_QUERY_STR_HOOK | Sets the Request's Query String Hook Function. |
HTTPc_PARAM_TYPE_REQ_HDR_TBL | Sets the Request's Header Table. |
HTTPc_PARAM_TYPE_REQ_HDR_HOOK | Sets the Request's Header Hook Function. |
HTTPc_PARAM_TYPE_REQ_FORM_TBL | Sets the Request's Form Table. |
HTTPc_PARAM_TYPE_REQ_BODY_CONTENT_TYPE | Sets the Request's Body Content Type. |
HTTPc_PARAM_TYPE_REQ_BODY_CONTENT_LEN | Sets the Request's Body Content Length. |
HTTPc_PARAM_TYPE_REQ_BODY_HOOK | Sets the Request's Hook Function for retrieving the data body. |
HTTPc_PARAM_TYPE_RESP_HDR_HOOK | Sets the Response's Header Hook Function. |
HTTPc_PARAM_TYPE_RESP_BODY_HOOK | Sets the Response's Hook Function for the Body received. |
HTTPc_PARAM_TYPE_TRANS_COMPLETE_CALLBACK | Sets the HTTP Transaction Complete Callback to notify the application that the Transaction is completed.This parameter is mandatory when the HTTPc_CFG_MODE_ASYNC_TASK_EN configuration is enabled. |
HTTPc_PARAM_TYPE_TRANS_ERR_CALLBACK | Sets the HTTP Transaction Error Callback to notify the application when an unexpected error occurred with an HTTP Transaction.This parameter is mandatory when the HTTPc_CFG_MODE_ASYNC_TASK_EN configuration is enabled. |
Example#
Listing - Request Setup Example Code#
CPU_BOOLEAN HTTPcApp_ReqPrepare (HTTPc_CONN_OBJ *p_req)
{
RTOS_ERR err;
/* ------------- INIT NEW REQUEST ------------ */
HTTPc_ReqClr(p_req, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* -------- SET STRING QUERY PARAMETERS ------ */
HTTPc_ReqSetParam(p_req,
HTTPc_PARAM_TYPE_REQ_QUERY_STR_HOOK,
&HTTPcApp_ReqQueryStrHook,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ------ SET REQUEST ADDITIONAL HEADERS ----- */
HTTPc_ReqSetParam(p_req,
HTTPc_PARAM_TYPE_REQ_HDR_HOOK,
&HTTPcApp_ReqHdrHook,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* -------- SET REQ/RESP HOOK FUNCTIONS ------ */
HTTPc_ReqSetParam(p_req,
HTTPc_PARAM_TYPE_RESP_HDR_HOOK,
&HTTPcApp_RespHdrHook,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
HTTPc_ReqSetParam(p_req,
HTTPc_PARAM_TYPE_RESP_BODY_HOOK,
&HTTPcApp_RespBodyHook,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ----- SET REQ/RESP CALLBACK FUNCTIONS ----- */
#if (HTTPc_CFG_MODE_ASYNC_TASK_EN == DEF_ENABLED)
HTTPc_ReqSetParam(p_req,
HTTPc_PARAM_TYPE_TRANS_COMPLETE_CALLBACK,
&HTTPcApp_TransDoneCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
HTTPc_ReqSetParam(p_req,
HTTPc_PARAM_TYPE_TRANS_ERR_CALLBACK,
&HTTPcApp_TransErrCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
#endif
return (DEF_OK);
}
HTTP Client Open Secure Connection with SSL-TSL#
Requirements#
To open a secure HTTP connection with the HTTP Client module, the below requirements are needed:
A network security module (such as Mocana - NanoSSL) is required.
The Micrium OS Network core stack needs to be configured accordingly (see section Transport Layer Security Configuration ).
The client side needs to install certificate authorities to authenticate the identity of each public key certificate sent by servers.
Refer to section Secure Sockets (TLS or SSL) for an example on how to use the Network module to open a secure socket for a client application.
HTTP Client parameters#
HTTP Client offers two parameters to configure the secure connection:
HTTPc_PARAM_TYPE_SECURE_COMMON_NAME
HTTPc_PARAM_TYPE_SECURE_TRUST_CALLBACK
The first parameter is optional and gives the option to specify the Common Name linked to the Secure Certificate to identify it with the certificate authorities. If this parameter is not set the server host name will be used.
The second parameter is mandatory to open a secure connection and therefore when this parameter is specified, the HTTP Client stack will assume that the connection to open must be secured. The parameter specified the hook function used by the secure module to ask the upper application to verify and validate the public key certificate send by the server.
Both parameters must be configured with the function HTTPc_ConnSetParam().
Example#
Listing - Secure Connection Example Code#
HTTPc_CONN_OBJ conn;
/*
*********************************************************************************************************
* HTTPcEx_ConnPrepare()
*
* Description : Example function to prepare the HTTPc Connection.
*
* Argument(s) : p_conn Pointer to HTTPc Connection object to set up.
*
* Return(s) : DEF_YES, if Connection preparation successful.
* DEF_NO, otherwise.
*********************************************************************************************************
*/
CPU_BOOLEAN HTTPcEx_ConnPrepare (HTTPc_CONN_OBJ *p_conn)
{
RTOS_ERR err;
/* ------------ INIT NEW CONNECTION ---------- */
HTTPc_ConnClr(p_conn, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ----------- SET CONN'S CALLBACKS ---------- */
#if (HTTPc_CFG_MODE_ASYNC_TASK_EN == DEF_ENABLED)
HTTPc_ConnSetParam(p_conn,
HTTPc_PARAM_TYPE_CONN_CONNECT_CALLBACK,
&HTTPcEx_ConnConnectCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
HTTPc_ConnSetParam(p_conn,
HTTPc_PARAM_TYPE_CONN_CLOSE_CALLBACK,
&HTTPcEx_ConnCloseCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
#endif
/* ----- SET CONNECTION SECURE PARAMETERS ---- */
HTTPc_ConnSetParam(p_conn,
HTTPc_PARAM_TYPE_SECURE_TRUST_CALLBACK
&HTTPcEx_ConnSecureCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
return (DEF_OK);
}
/*
*********************************************************************************************************
* HTTPcEx_ConnCloseCallback()
*
* Description : Example Callback Function to validate public key from server.
*
* Argument(s) : p_cert_dn Pointer to certificate distinguished name.
*
* reason Reason why certificate is not trusted:
* NET_SOCK_SECURE_UNTRUSTED_BY_CA
* NET_SOCK_SECURE_EXPIRE_DATE
* NET_SOCK_SECURE_INVALID_DATE
* NET_SOCK_SECURE_SELF_SIGNED
*
* Return(s) : DEF_YES, if certificate is valid.
* DEF_NO, otherwise.
*********************************************************************************************************
*/
CPU_BOOLEAN HTTPcEx_ConnCloseCallback (void *p_cert_dn,
NET_SOCK_SECURE_UNTRUSTED_REASON reason)
{
return (DEF_YES);
}
HTTP Client Add Additional Header fields to an HTTP Request#
HTTP Client supports the addition of header fields to an HTTP request:
The preprocessor macro HTTPc_CFG_HDR_TX_EN must be set to DEF_ENABLED.
HTTPc_HDR objects must be used to set up headed fields to add.
Two methods are offered by the HTTP Client stack to add header fields:
Passing a header fields table to to the HTTP Client stack.
Using a hook function that will ask the application for each header field to add to the request.
Some header fields are taken care of by the HTTP Client module and must therefore not be added by the application :
Host
Content-Type
Content-Length
Transfer-Encoding
Connection
Using a Header Fields Table#
With the first option, before sending the HTTP request, the application can prepare a table of HTTPc_HDR objects that the HTTP Client will include in the request. The API function HTTPc_ReqSetParam() must be used with the parameter type HTTPc_PARAM_TYPE_REQ_HDR_TBL to pass out the table to the HTTP Client stack.
Listing - Adding Header Fields with a Table Example Code#
#define HTTPc_CFG_HDR_NBR_MAX 10
#define HTTPc_CFG_HDR_VAL_LEN_MAX 100
HTTPc_HDR HTTPc_ReqHdrTbl[HTTPc_CFG_HDR_NBR_MAX];
CPU_CHAR HTTPc_ReqHdrValTbl[HTTPc_CFG_HDR_NBR_MAX][HTTPc_CFG_HDR_VAL_LEN_MAX];
/*
*********************************************************************************************************
* HTTPc_ReqPrepareHdr()
*
* Description : Prepare the HTTP header table.
*
* Argument(s) : p_tbl Variable that will received the pointer to header table.
*
* Return(s) : Number of Header fields in the table.
*********************************************************************************************************
*/
static CPU_INT08U HTTPc_ReqPrepareHdr (HTTPc_KEY_VAL **p_tbl)
{
HTTPc_HDR *p_hdr;
p_hdr = &HTTPc_ReqHdrTbl[0];
p_hdr->ValPtr = &HTTPc_ReqHdrValTbl[0][0];
p_hdr->HdrField = HTTP_HDR_FIELD_ACCEPT;
Str_Copy_N(p_hdr->ValPtr, "text/*", HTTPc_CFG_HDR_VAL_LEN_MAX);
p_hdr->ValLen = Str_Len_N(p_hdr->ValPtr, HTTPc_CFG_HDR_VAL_LEN_MAX);
*p_ext_hdr_tbl = &HTTPc_ReqHdrTbl[0];
return (1);
}
/*
*********************************************************************************************************
* HTTPc_ReqPrepare()
*
* Description : Prepare the HTTP request to send.
*
* Argument(s) : p_req Pointer to the HTTP Request object to configure.
*
* Return(s) : DEF_OK, if the request was configured successfully.
* DEF_FAIL, otherwise.
*********************************************************************************************************
*/
static CPU_BOOLEAN HTTPc_ReqPrepare (HTTPc_REQ_OBJ *p_req)
{
HTTPc_PARAM_TBL tbl_obj;
HTTPc_HDR *p_hdr_tbl;
CPU_INT08U hdr_nbr;
HTTPc_ERR err;
/* ---------- SET HEADER FIELDS DATA --------- */
hdr_nbr = HTTPc_ReqPrepareHdr(&p_hdr_tbl);
if (hdr_nbr <= 0) {
return (DEF_FAIL);
}
/* -------- SET HEADER FIELDS PARAMETER ------ */
tbl_obj.EntryNbr = hdr_nbr;
tbl_obj.TblPtr = (void *)p_hdr_tbl;
HTTPc_ReqSetParam(p_req, HTTPc_PARAM_TYPE_REQ_HDR_TBL, &tbl_obj, &err);
if (err != HTTPc_ERR_NONE) {
return (DEF_FAIL);
}
... /* TODO other operations on request if necessary. */
return (DEF_OK);
Using a Hook Function#
The Second option is to set up a hook function. The hook function will be called by the HTTP Client core to add a Header Field to the request. The hook function will be called until it return DEF_YES to notified the HTTP Client stack that all the fields have been added. The API function HTTPc_ReqSetParam() must be used with the parameter type HTTPc_PARAM_TYPE_REQ_HDR_HOOK to pass out hook function pointer to the HTTP Client stack.
Listing - Adding Header Fields with a Hook Example Code#
#define HTTPc_CFG_HDR_NBR_MAX 10
#define HTTPc_CFG_HDR_VAL_LEN_MAX 100
CPU_INT08U HTTPc_ReqHdrIx;
HTTPc_HDR HTTPc_ReqHdrTbl[HTTPc_CFG_HDR_NBR_MAX];
CPU_CHAR HTTPc_ReqHdrValTbl[HTTPc_CFG_HDR_NBR_MAX][HTTPc_CFG_HDR_VAL_LEN_MAX];
/*
*********************************************************************************************************
* HTTPc_ReqPrepare()
*
* Description : Prepare the HTTP request to send.
*
* Argument(s) : p_req Pointer to the HTTP Request object to configure.
*
* Return(s) : DEF_OK, if the request was configured successfully.
* DEF_FAIL, otherwise.
*********************************************************************************************************
*/
static CPU_BOOLEAN HTTPc_ReqPrepare (HTTPc_REQ_OBJ *p_req)
{
HTTPc_ERR err;
/* -------- SET STRING QUERY PARAMETER ------- */
HTTPc_ReqSetParam(p_req, HTTPc_PARAM_TYPE_REQ_HDR_HOOK, &HTTPc_ReqHdrHook, &err);
if (err != HTTPc_ERR_NONE) {
return (DEF_FAIL);
}
p_req->UserDataPtr = (void *)&HTTPc_ReqHdrIx;
... /* TODO other operations on request if necessary. */
return (DEF_OK);
}
/*
*********************************************************************************************************
* HTTPc_ReqHdrHook()
*
* Description : Hook function to retrieve the header fields to include in the HTTP request.
*
* Argument(s) : p_conn Pointer to the HTTP Connection object.
*
* p_req Pointer to the HTTP Request object.
*
* p_hdr Variable that will received the pointer to the Header field object.
*
* Return(s) : DEF_YES, if all the header fields to include have been passed.
* DEF_NO, otherwise.
*********************************************************************************************************
*/
static CPU_BOOLEAN HTTPc_ReqHdrHook (HTTPc_CONN_OBJ *p_conn,
HTTPc_REQ_OBJ *p_req,
HTTPc_HDR **p_hdr)
{
HTTPc_HDR *p_hdr_item;
CPU_INT08U index;
index = *(CPU_INT08U)p_req->UserDataPtr;
switch(index) {
case 0:
p_hdr_item = &HTTPc_ReqHdrTbl[0];
p_hdr_item->ValPtr = &HTTPc_ReqHdrValTbl[0][0];
p_hdr_item->HdrField = HTTP_HDR_FIELD_ACCEPT;
(void)Str_Copy_N(p_hdr_item->ValPtr, "text/*", HTTPc_CFG_HDR_VAL_LEN_MAX);
p_hdr_item->ValLen = Str_Len_N(p_hdr_item->ValPtr, HTTPc_CFG_HDR_VAL_LEN_MAX);
*p_hdr = p_hdr_item;
index++;
*(CPU_INT08U)p_req->UserDataPtr = index;
return (DEF_NO);
case 1:
p_hdr_item = &HTTPc_ReqHdrTbl[1];
p_hdr_item->ValPtr = &HTTPc_ReqHdrValTbl[1][0];
p_hdr_item->HdrField = HTTP_HDR_FIELD_DATE;
(void)Str_Copy_N(p_hdr_item->ValPtr, "Thursday, 21-Aug-14 02:15:31 GMT", HTTPc_CFG_HDR_VAL_LEN_MAX);
p_hdr_item->ValLen = Str_Len_N(p_hdr_item->ValPtr, HTTPc_CFG_HDR_VAL_LEN_MAX);
*p_hd = p_hdr_item;
index = 0;
*(CPU_INT08U)p_req->UserDataPtr = index;
return (DEF_YES);
default:
*p_hdr = DEF_NULL;
index = 0;
*(CPU_INT08U)p_req->UserDataPtr = index;
return (DEF_YES);
}
}
HTTP Client Request's Body Standard Transfer#
The POST and PUT methods can be used to transfer data to the HTTP server. The data is included in the body part of the HTTP request.
Additional HTTP header fields must be included when a body is present. The content type of the data must be specified with the Content-Type header field, and for a standard transfer, the length of the data must be specified with the Content-Length header field. Those headers will be added automatically by the HTTP Client stack after the required parameters are configured.
The function HTTPc_ReqSetParam() must be used to configure the additional parameters necessary when data must be transmitted the standard way. Three parameters must be set up :
HTTPc_PARAM_TYPE_REQ_BODY_CONTENT_TYPE
HTTPc_PARAM_TYPE_REQ_BODY_CONTENT_LEN
HTTPc_PARAM_TYPE_REQ_BODY_HOOK
The first parameter sets the content-type of the data, the second the length of the data, and the third sets the hook function that will be used by the HTTP Client module to retrieve the data.
Example#
Since all the API function are in blocking mode in the example below, the HTTPc objects and string can be allocated on the application stack without problems. |
---|
The example below implements a function to send a PUT request :
An HTTP Connection is set up
An HTTP request is configured with the three body parameters: content-type, content-length, and hook function.
The Connection is open.
The request is sent.
Listing - Standard Body Transfer Function Example Code#
CPU_CHAR index_html[1024];
/*
*********************************************************************************************************
* HTTPcEx_ReqSendPUT_Standard()
*
* Description : Example function to send a HTTP PUT request with the standard transfer (not chunked).
*
* Argument(s) : none.
*
* Return(s) : DEF_YES, is request sent successfully.
* DEF_NO, otherwise.
*********************************************************************************************************
*/
CPU_BOOLEAN HTTPcEx_ReqSendPUT_Standard (void)
{
HTTPc_CONN_OBJ conn;
HTTPc_REQ_OBJ req;
HTTPc_RESP_OBJ resp;
CPU_CHAR buf[512];
HTTPc_FLAGS flags;
HTTP_CONTENT_TYPE content_type;
CPU_SIZE_T content_len;
CPU_SIZE_T str_len;
CPU_BOOLEAN result;
RTOS_ERR err;
/* ------------ INIT NEW CONNECTION ---------- */
HTTPc_ConnClr(&conn, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ---------- SET CONNECTION PARAM ----------- */
#if (HTTPc_CFG_MODE_ASYNC_TASK_EN == DEF_ENABLED)
HTTPc_ConnSetParam(&conn,
HTTPc_PARAM_TYPE_CONN_CLOSE_CALLBACK,
&HTTPcEx_ConnCloseCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
#endif
/* -------------- INIT NEW REQUEST------------ */
HTTPc_ReqClr(&req, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ------- SET REQUEST BODY PARAMETERS ------- */
content_type = HTTP_CONTENT_TYPE_HTML;
HTTPc_ReqSetParam(&req,
HTTPc_PARAM_TYPE_REQ_BODY_CONTENT_TYPE,
&content_type,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
content_len = STATIC_INDEX_HTML_LEN;
HTTPc_ReqSetParam(&req,
HTTPc_PARAM_TYPE_REQ_BODY_CONTENT_LEN,
&content_len,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
HTTPc_ReqSetParam(&req,
HTTPc_PARAM_TYPE_REQ_BODY_HOOK,
&HTTPcEx_ReqBodyHook,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* -------- SET TRANSACTION CALLBACKS -------- */
#if (HTTPc_CFG_MODE_ASYNC_TASK_EN == DEF_ENABLED)
HTTPc_ReqSetParam(&req,
HTTPc_PARAM_TYPE_TRANS_ERR_CALLBACK,
&HTTPcEx_TransErrCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
#endif
/* ------------- OPEN CONNECTION ------------- */
str_len = Str_Len("www.example.com");
flags = HTTPc_FLAG_NONE;
result = HTTPc_ConnOpen(&conn,
&buf,
APP_HTTPc_CFG_BUF_SIZE,
"www.example.com",
str_len,
flags,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
if (result != DEF_OK) {
return (DEF_FAIL);
}
/* ------------ SEND HTTP REQUEST ------------ */
str_len = Str_Len("/index.html");
flags = HTTPc_FLAG_NONE;
result = HTTPc_ReqSend(&conn,
&req,
&resp,
HTTP_METHOD_PUT,
"/index.html",
str_len,
flags,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
return (DEF_OK);
}
The example below is a first implementation of the hook function to retrieve the request body data from the application. In this example, the data is retrieved from an existing application buffer (index_html) and the hook function only set up the data pointer and the length of the data.
Listing - Request Body Hook Function Example Code #1#
/*
*********************************************************************************************************
* HTTPcEx_ReqBodyHook()
*
* Description : Example Hook function to transfer data in request with the standard transfer.
*
* This function let you the choice to set the pointer to the application data (with p_data)
* that the HTTP Client stack will take care of transferring; or to directly copy the data
* in the HTTP transmit buffer (with p_buf).
*
* Argument(s) : p_conn Pointer to the current HTTPc Connection object.
*
* p_req Pointer to the current HTTPc Request object.
*
* p_data Pointer to the application data.
*
* p_buf Pointer to the HTTP buffer.
*
* buf_len Buffer's length.
*
* p_data_len Variable that will return the data length passed by the application.
*
* Return(s) : DEF_YES, if all data as been passed.
* DEF_NO, if data still remaining to be passed by the application.
*********************************************************************************************************
*/
static CPU_BOOLEAN HTTPcEx_ReqBodyHook (HTTPc_CONN_OBJ *p_conn,
HTTPc_REQ_OBJ *p_req,
void **p_data,
CPU_CHAR *p_buf,
CPU_INT16U buf_len,
CPU_INT16U *p_data_len)
{
CPU_INT16U size;
CPU_INT16U str_len;
*p_data = &index_html[0];
str_len = Str_Len(&index_html[0]);
Str_Copy_N(p_buf, &index_html[0], str_len);
*p_data_len = str_len;
return (DEF_YES);
}
The example below is a second implementation of the hook function to retrieve the request body data from the application. In this example, the data is retrieved from a file that is accessed using Micrium OS File System and directly copied into the HTTP transmit buffer.
Listing - Request Body Hook Function Example Code #2#
static CPU_BOOLEAN HTTPcEx_ReqBodyHook (HTTPc_CONN_OBJ *p_conn,
HTTPc_REQ_OBJ *p_req,
void **p_data,
CPU_CHAR *p_buf,
CPU_INT16U buf_len,
CPU_INT16U *p_data_len)
{
CPU_BOOLEAN finish;
CPU_SIZE_T file_rem;
CPU_SIZE_T size;
CPU_SIZE_T size_rd;
FS_FILE_HANDLE file_handle;
FS_ENTRY_INFO file_info;
FS_FILE_SIZE file_pos;
RTOS_ERR err;
*p_data = DEF_NULL;
file_handle = FSFile_Open(FSWrkDir_NullHandle,
"ram0/index.html",
FS_FILE_ACCESS_MODE_RD,
&err);
if (err.Code != RTOS_ERR_NONE) {
// TODO: Handle error.
*p_data_len = 0u;
finish = DEF_YES;
return (finish);
}
FSFile_Query(file_handle,
&file_info,
&err);
if (err.Code != RTOS_ERR_NONE) {
// TODO: Handle error.
*p_data_len = 0;
finish = DEF_YES;
goto exit_close;
}
file_pos = FSFile_PosGet(file_handle,
&err);
if (err.Code != RTOS_ERR_NONE) {
// TODO: Handle error.
*p_data_len = 0;
finish = DEF_YES;
goto exit_close;
}
file_rem = file_info.Size - file_pos;
if (file_rem <= 0) {
*p_data_len = 0;
finish = DEF_YES;
goto exit_close;
}
size = DEF_MIN(file_rem, buf_len);
size_rd = FSFile_Rd(file_handle,
p_buf,
size,
&err);
if (err.Code != RTOS_ERR_NONE) {
// TODO: Handle error.
*p_data_len = 0u;
finish = DEF_YES;
goto exit_close;
}
*p_data_len = size_rd;
finish = DEF_NO;
exit_close:
FSFile_Close(file_handle, &err);
if (err.Code != RTOS_ERR_NONE) {
// TODO: Handle error.
}
return (finish);
}
HTTP Client Chunked Transfer Encoding#
The POST and PUT methods can be used to transfer data to the HTTP server. The data is included in the body part of the HTTP request.
When the size of the data to transmit is unknown before starting the HTTP request, the Chunked Transfer Encoding can be used. It will split the data into chunks of known size and will send an empty chunk to advertise the end of the data.
Additional HTTP header fields must be included when a body is present. The content type of the data must be specified with the Content-Type header field and for the Chunked Transfer encoding the Transfer-Encoding header field must be specified. Those headers will be added automatically by the HTTP Client module after the required parameters are configured. For more details, refer to section Chunked Transfer Encoding.
The function HTTPc_ReqSetParam() must be used to configure the additional parameters necessary when data is transmitted in chunks. Three parameters must be set up :
HTTPc_PARAM_TYPE_REQ_BODY_CONTENT_TYPE
HTTPc_PARAM_TYPE_REQ_BODY_CHUNK
HTTPc_PARAM_TYPE_REQ_BODY_HOOK
The first parameter is to set the content-type of the data, the second is a Boolean to enable the Chunked Transfer Encoding and the third is to set the hook function that will be used by the HTTP Client module to retrieve the data.
Example#
Since all the API functions are in blocking mode in the example below, the HTTPc objects and string can be allocated on the application stack without problems. |
---|
The example below implements a function to send a PUT request :
An HTTP Connection is configured.
An HTTP request is configured with the three body parameters: content-type, chunk enabled and hook function.
The Connection is open.
The request is sent.
Listing - Chunked Transfer Encoding Example Code#
/*
*********************************************************************************************************
* HTTPcEx_ReqSendPUT_Chunked()
*
* Description : Example function to send a HTTP PUT request with the Chunked Transfer Encoding.
*
* Argument(s) : none.
*
* Return(s) : DEF_YES, is request sent successfully.
* DEF_NO, otherwise.
*********************************************************************************************************
*/
CPU_BOOLEAN HTTPcEx_ReqSendPUT_Chunked (void)
{
CPU_BOOLEAN result;
CPU_BOOLEAN chunk_en;
CPU_CHAR buf[512];
CPU_SIZE_T str_len;
HTTPc_CONN_OBJ conn;
HTTPc_REQ_OBJ req;
HTTPc_RESP_OBJ resp;
HTTP_CONTENT_TYPE content_type;
RTOS_ERR err;
/* ---------- INIT NEW CONNECTION --------- */
HTTPc_ConnClr(&conn, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* -------- SET CONNECTION PARAM ---------- */
#if (HTTPc_CFG_MODE_ASYNC_TASK_EN == DEF_ENABLED)
HTTPc_ConnSetParam(&conn,
HTTPc_PARAM_TYPE_CONN_CLOSE_CALLBACK,
&HTTPcEx_ConnCloseCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
#endif
/* ----- SET REQUEST BODY PARAMETERS ------ */
content_type = HTTP_CONTENT_TYPE_JSON;
HTTPc_ReqSetParam(&req,
HTTPc_PARAM_TYPE_REQ_BODY_CONTENT_TYPE,
&content_type,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
chunk_en = DEF_YES;
HTTPc_ReqSetParam(&req,
HTTPc_PARAM_TYPE_REQ_BODY_CHUNK,
&chunk_en,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
HTTPc_ReqSetParam(&req,
HTTPc_PARAM_TYPE_REQ_BODY_HOOK,
&HTTPcEx_ReqBodyHook,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
#if (HTTPc_CFG_MODE_ASYNC_TASK_EN == DEF_ENABLED)
HTTPc_ReqSetParam(&req,
HTTPc_PARAM_TYPE_TRANS_ERR_CALLBACK,
&HTTPcEx_TransErrCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
#endif
/* ----------- OPEN CONNECTION ------------ */
str_len = Str_Len("www.example.com");
result = HTTPc_ConnOpen(&conn,
&buf,
APP_HTTPc_CFG_BUF_SIZE,
"www.example.com",
str_len,
HTTPc_FLAG_NONE,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
if (result != DEF_OK) {
return (DEF_FAIL);
}
/* ---------- SEND HTTP REQUEST ----------- */
str_len = Str_Len("/");
result = HTTPc_ReqSend(&conn,
&req,
&resp,
HTTP_METHOD_PUT,
"/",
str_len,
HTTPc_FLAG_NONE,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
return (DEF_OK);
}
For examples on the On Request Body hook function, refer to section Request's Body Standard Transfer since the hook function is used regardless of the transfer mode.
HTTP Client Query String#
A Query String is a set of Key-Value pairs or single values added at the end of the request's URL after a question mark character "?". Each field of the Query is separated by the "&" character. For more details, see section Query String .
The HTTP Client module supports the addition of a Query String to an HTTP request:
The preprocessor macro HTTPc_CFG_QUERY_STR_EN must be set to DEF_ENABLED.
HTTPc_KEY_VAL type's objects must be used to setup a Query String field. When the field is a single string and not a pair of key-value, the pointer to the value can be left blank and only the pointer to the key will be used.
Two methods are offered by the HTTP Client module to add Query String:
Passing a Key-Value Pairs' Table to the HTTP Client stack.
Using a hook function that will ask the application for each Key-Value Pair.
Using a Key-Value Pairs' Table#
For the first option, before sending the HTTP request, the application can prepare a table of HTTPc_KEY_VAL objects that the HTTP Client will include in the Query String. The API function HTTPc_ReqSetParam() must be used with the parameter type HTTPc_PARAM_TYPE_REQ_QUERY_STR_TBL to pass out the table to the HTTP Client stack.
Listing - Adding a Query String with Table Example Code#
#define HTTPc_CFG_QUERY_STR_NBR_MAX 10
#define HTTPc_CFG_QUERY_STR_KEY_LEN_MAX 50
#define HTTPc_CFG_QUERY_STR_VAL_LEN_MAX 100
HTTPc_KEY_VAL HTTPc_ReqQueryStrTbl[HTTPc_CFG_QUERY_STR_NBR_MAX];
CPU_CHAR HTTPc_ReqQueryStrKeyTbl[HTTPc_CFG_QUERY_STR_NBR_MAX][HTTPc_CFG_QUERY_STR_KEY_LEN_MAX];
CPU_CHAR HTTPc_ReqQueryStrValTbl[HTTPc_CFG_QUERY_STR_NBR_MAX][HTTPc_CFG_QUERY_STR_VAL_LEN_MAX];
/*
*********************************************************************************************************
* HTTPc_ReqPrepareQueryStr()
*
* Description : Prepare the Query String Table.
*
* Argument(s) : p_tbl Variable that will received the pointer to the Query String table.
*
* Return(s) : Number of fields in the Query String table.
*********************************************************************************************************
*/
static CPU_INT08U HTTPc_ReqPrepareQueryStr (HTTPc_KEY_VAL **p_tbl)
{
HTTPc_KEY_VAL *p_key_val;
/* ------------- SET FIRST QUERY ------------- */
p_key_val = &HTTPc_ReqQueryStrTbl[0];
p_key_val->KeyPtr = &HTTPc_ReqQueryStrKeyTbl[0][0];
p_key_val->ValPtr = &HTTPc_ReqQueryStrValTbl[0][0];
(void)Str_Copy_N(p_key_val->KeyPtr, "name", HTTPc_CFG_QUERY_STR_KEY_LEN_MAX);
(void)Str_Copy_N(p_key_val->ValPtr, "Jonh", HTTPc_CFG_QUERY_STR_VAL_LEN_MAX);
p_key_val->KeyLen = Str_Len_N(p_key_val->KeyPtr, HTTPc_CFG_QUERY_STR_KEY_LEN_MAX);
p_key_val->ValLen = Str_Len_N(p_key_val->ValPtr, HTTPc_CFG_QUERY_STR_VAL_LEN_MAX);
/* ------------ SET SECOND QUERY ------------- */
p_key_val = &HTTPc_ReqQueryStrTbl[1];
p_key_val->KeyPtr = &HTTPc_ReqQueryStrKeyTbl[1][0];
p_key_val->ValPtr = DEF_NULL;
(void)Str_Copy_N(p_key_val->KeyPtr, "active", HTTPc_CFG_QUERY_STR_KEY_LEN_MAX);
p_key_val->KeyLen = Str_Len_N(p_key_val->KeyPtr, HTTPc_CFG_QUERY_STR_KEY_LEN_MAX);
*p_tbl = &HTTPc_ReqQueryStrTbl[0];
return (2);
}
/*
*********************************************************************************************************
* HTTPc_ReqPrepare()
*
* Description : Prepare the HTTP request to send.
*
* Argument(s) : p_req Pointer to the HTTP Request object to configure.
*
* Return(s) : DEF_OK, if the request was configured successfully.
* DEF_FAIL, otherwise.
*********************************************************************************************************
*/
static CPU_BOOLEAN HTTPc_ReqPrepare (HTTPc_REQ_OBJ *p_req)
{
HTTPc_PARAM_TBL tbl_obj;
HTTPc_KEY_VAL *p_query_str_tbl;
CPU_INT08U query_nbr;
RTOS_ERR err;
/* -------- SET STRING QUERY DATA ------------ */
query_nbr = HTTPc_ReqPrepareQueryStr(&p_query_str_tbl);
if (query_nbr <= 0) {
return (DEF_FAIL);
}
/* ------ SET STRING QUERY PARAMETERS -------- */
tbl_obj.EntryNbr = query_nbr;
tbl_obj.TblPtr = (void *)p_query_str_tbl;
HTTPc_ReqSetParam(p_req, HTTPc_PARAM_TYPE_REQ_QUERY_STR_TBL, &tbl_obj, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
... /* TODO other operations on request if necessary. */
return (DEF_OK);
}
Using a Hook Function#
The Second option is to set up a hook function. The hook function will be called by the HTTP Client module to add a field to the Query String. The hook function will be called until it returns DEF_YES to notified the HTTP Client module that all the fields have been added. The API function HTTPc_ReqSetParam() must be used with the parameter type HTTPc_PARAM_TYPE_REQ_QUERY_STR_HOOK to pass out hook function pointer to the HTTP Client module.
Listing - Adding Query String with a Hook Example Code#
#define HTTPc_CFG_QUERY_STR_NBR_MAX 10
#define HTTPc_CFG_QUERY_STR_KEY_LEN_MAX 50
#define HTTPc_CFG_QUERY_STR_VAL_LEN_MAX 100
CPU_INT08U HTTPc_ReqQueryStrIx;
HTTPc_KEY_VAL HTTPc_ReqQueryStrTbl[HTTPc_CFG_QUERY_STR_NBR_MAX];
CPU_CHAR HTTPc_ReqQueryStrKeyTbl[HTTPc_CFG_QUERY_STR_NBR_MAX][HTTPc_CFG_QUERY_STR_KEY_LEN_MAX];
CPU_CHAR HTTPc_ReqQueryStrValTbl[HTTPc_CFG_QUERY_STR_NBR_MAX][HTTPc_CFG_QUERY_STR_VAL_LEN_MAX];
/*
*********************************************************************************************************
* HTTPc_ReqPrepare()
*
* Description : Prepare the HTTP request to send.
*
* Argument(s) : p_req Pointer to the HTTP Request object to configure.
*
* Return(s) : DEF_OK, if the request was configured successfully.
* DEF_FAIL, otherwise.
*********************************************************************************************************
*/
static CPU_BOOLEAN HTTPc_ReqPrepare (HTTPc_REQ_OBJ *p_req)
{
RTOS_ERR err;
/* -------- SET STRING QUERY PARAMETER ------- */
HTTPc_ReqSetParam(p_req,
HTTPc_PARAM_TYPE_REQ_QUERY_STR_HOOK,
&HTTPc_ReqQueryStrHook,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
p_req->UserDataPtr = (void *)&HTTPc_ReqQueryStrIx;
... /* TODO other operations on request if necessary. */
return (DEF_OK);
}
/*
*********************************************************************************************************
* HTTPc_ReqQueryStrHook()
*
* Description : Hook function to retrieve the data of the Query String.
*
* Argument(s) : p_conn Pointer to the HTTP Connection object.
*
* p_req Pointer to the HTTP Request object.
*
* p_key_val Variable that will receive the pointer to the Key-Val object.
*
* Return(s) : DEF_YES, if all the fields of the Query String have been passed.
* DEF_NO, otherwise.
*********************************************************************************************************
*/
static CPU_BOOLEAN HTTPc_ReqQueryStrHook (HTTPc_CONN_OBJ *p_conn,
HTTPc_REQ_OBJ *p_req,
HTTPc_KEY_VAL **p_key_val)
{
HTTPc_KEY_VAL *p_kvp;
CPU_INT08U index;
index = *(CPU_INT08U)p_req->UserDataPtr;
switch(index) {
case 0:
p_kvp = &HTTPc_ReqQueryStrTbl[0];
p_kvp->KeyPtr = &HTTPc_ReqQueryStrKeyTbl[0][0];
p_kvp->ValPtr = &HTTPc_ReqQueryStrValTbl[0][0];
(void)Str_Copy_N(p_kvp->KeyPtr, "name", HTTPc_CFG_QUERY_STR_KEY_LEN_MAX);
(void)Str_Copy_N(p_kvp->ValPtr, "Jonh", HTTPc_CFG_QUERY_STR_VAL_LEN_MAX);
p_kvp->KeyLen = Str_Len_N(p_kvp->KeyPtr, HTTPc_CFG_QUERY_STR_KEY_LEN_MAX);
p_kvp->ValLen = Str_Len_N(p_kvp->ValPtr, HTTPc_CFG_QUERY_STR_VAL_LEN_MAX);
*p_key_val = p_kvp;
index++;
*(CPU_INT08U)p_req->UserDataPtr = index;
return (DEF_NO);
case 1:
p_kvp = &HTTPc_ReqQueryStrTbl[1];
p_kvp->KeyPtr = &HTTPc_ReqQueryStrKeyTbl[1][0];
p_kvp->ValPtr = DEF_NULL;
(void)Str_Copy_N(p_kvp->KeyPtr, "active", HTTPc_CFG_QUERY_STR_KEY_LEN_MAX);
p_kvp->KeyLen = Str_Len_N(p_kvp->KeyPtr, HTTPc_CFG_QUERY_STR_KEY_LEN_MAX);
*p_key_val = p_kvp;
index = 0;
*(CPU_INT08U)p_req->UserDataPtr = index;
return (DEF_YES);
default:
*p_key_val = DEF_NULL;
index = 0;
*(CPU_INT08U)p_req->UserDataPtr = index;
return (DEF_YES);
}
}
HTTP Client Form Submission#
HTTP Client offers several structures and API functions to simplify the formatting and transmission of Forms for the development of an HTTP Client application.
For more details on HTTP Forms, see section Form .
Form Field Types#
HTTP Client offers three types of form field. Each type is associated with a structure that the application can used to create objects:
Key-Value Pair : Simple pair of key and value strings. Can be used with the Application type form and the Multipart type form.
Extended Key-Value Pair : Key-Value pair where the string value is not specified but a hook function is to allow the HTTP Client stack to retrieve the value when the form is formatted. Can be used with the Multipart type form only.
Multipart File : Use to upload file to an HTTP server inside a Multipart type form. Can be used with the Multipart type form only.
Form API#
The application should incorporate all the form fields into a table using the API functions offered below :
HTTPc_FormAddKeyVal() to add a simple Key-Value pair object to a form table.
HTTPc_FormAddKeyValExt() to add a Extended Key-Value pair object to a form table.
HTTPc_FormAddFile() to add a Multipart File object to a form table.
Once the form fields' table is created, two possibilities are offered.
The first option is valid only if the table contains simple Key-Value pairs and consists of formatting the form on the application side with one of the API functions below:
HTTPc_FormAppFmt() to format the table into an Application-type form.
HTTPc_FormMultipartFmt() to format the table into a Multipart-type form.
Afterwards the application can transmit the formatted form like any other body types.
The second option is to pass the form fields table to the HTTP Client module so that the formatting can be done internally by the HTTP Client core. This option allows you to have a different form field type in the table. The HTTP Client module will take care of calling the hook functions to recover data from the application for extended Key-Value pair object and Multipart File objects.
The form fields table can be passed to the HTTP Client module by calling the HTTPc_ReqSetParam() function will the parameter type HTTPc_PARAM_TYPE_REQ_FORM_TBL and the macro configuration HTTPc_CFG_FORM_EN must be set to DEF_ENABLED.
Examples#
Example #1: Application Type Form with the form formatting on the application side#
Listing - Form Submission Example Code #1#
#define HTTP_SERVER_HOSTNAME "www.example.com"
#define HTTPc_EX_CFG_CONN_BUF_SIZE 512
#define HTTPc_EX_CFG_FORM_FIELD_NBR_MAX 10
#define HTTPc_EX_CFG_FORM_BUF_SIZE 4096
#define HTTPc_EX_CFG_KEY_LEN_MAX 50
#define HTTPc_EX_CFG_VAL_LEN_MAX 100
HTTPc_CONN_OBJ HTTPcEx_Conn;
CPU_CHAR HTTPcEx_ConnBuf[HTTPc_CFG_CONN_BUF_SIZE];
HTTPc_REQ_OBJ HTTPcEx_Req;
HTTPc_RESP_OBJ HTTPcEx_Resp;
HTTPc_FORM_TBL_FIELD HTTPcEx_ReqFormTbl[HTTPc_EX_CFG_FORM_FIELD_NBR_MAX];
CPU_CHAR HTTPcEx_FormBufTbl[HTTPc_EX_CFG_FORM_BUF_SIZE];
HTTPc_KEY_VAL HTTPcEx_KeyVal_Tbl[HTTPc_EX_CFG_FORM_FIELD_NBR_MAX];
CPU_CHAR HTTPcEx_KeyVal_KeyTbl[HTTPc_EX_CFG_FORM_FIELD_NBR_MAX][HTTPc_EX_CFG_KEY_LEN_MAX];
CPU_CHAR HTTPcEx_KeyVal_ValTbl[HTTPc_EX_CFG_FORM_FIELD_NBR_MAX][HTTPc_EX_CFG_VAL_LEN_MAX];
/*
*********************************************************************************************************
* HTTPcEx_ReqSendFormApp()
*
* Description : Example function to send an HTTP POST request containing an Application type form.
*
* Argument(s) : None.
*
* Return(s) : DEF_OK, if the HTTP transaction was successful.
* DEF_FAIL, otherwise.
*********************************************************************************************************
*/
CPU_BOOLEAN HTTPcEx_ReqSendFormApp (void)
{
HTTPc_CONN_OBJ *p_conn;
HTTPc_REQ_OBJ *p_req;
HTTPc_RESP_OBJ *p_resp;
CPU_CHAR *p_buf;
CPU_CHAR *p_data;
HTTPc_FORM_TBL_FIELD *p_form_tbl;
CPU_INT08U form_nbr;
CPU_INT16U content_len;
RTOS_ERR err;
p_conn = &HTTPcEx_ConnTbl[0];
p_req = &HTTPcEx_ReqTbl[0];
p_resp = &HTTPcEx_RespTbl[0];
p_buf = &HTTPcEx_BufTbl[0][0];
/* ------------- SET FORM TO SEND ------------ */
form_nbr = HTTPcEx_ReqPrepareFormApp(&p_form_tbl);
if (form_nbr <= 0) {
return (DEF_FAIL);
}
p_data = &HTTPcEx_FormBufTbl[0];
content_len = HTTPc_FormMultipartFmt(p_data,
APP_HTTPc_CFG_FORM_BUF_SIZE,
p_form_tbl,
form_nbr,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ------------ INIT NEW CONNECTION ---------- */
HTTPc_ConnClr(p_conn, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ----------- SET CONN'S CALLBACKS ---------- */
#if (HTTPc_CFG_MODE_ASYNC_TASK_EN == DEF_ENABLED)
HTTPc_ConnSetParam(p_conn,
HTTPc_PARAM_TYPE_CONN_CLOSE_CALLBACK,
&HTTPcEx_ConnCloseCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
#endif
/* ------------- INIT NEW REQUEST ------------ */
HTTPc_ReqClr(p_req, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ------- SET REQUEST BODY PARAMETERS ------- */
content_type = HTTP_CONTENT_TYPE_MULTIPART_FORM;
HTTPc_ReqSetParam(p_req,
HTTPc_PARAM_TYPE_REQ_BODY_CONTENT_TYPE,
&content_type,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
HTTPc_ReqSetParam(p_req,
HTTPc_PARAM_TYPE_REQ_BODY_CONTENT_LEN,
&content_len,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
HTTPc_ReqSetParam(p_req,
HTTPc_PARAM_TYPE_REQ_BODY_HOOK,
&HTTPcEx_ReqBodyHook,
&err);
if (err != HTTPc_ERR_NONE) {
return (DEF_FAIL);
}
/* ----------- SET REQ'S CALLBACKS ----------- */
#if (HTTPc_CFG_MODE_ASYNC_TASK_EN == DEF_ENABLED)
HTTPc_ReqSetParam(p_req,
HTTPc_PARAM_TYPE_TRANS_ERR_CALLBACK,
&HTTPcEx_TransErrCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
#endif
/* ------------- OPEN CONNECTION ------------- */
str_len = Str_Len(HTTP_SERVER_HOSTNAME);
result = HTTPc_ConnOpen(p_conn,
p_buf,
HTTPc_EX_CFG_BUF_SIZE,
HTTP_SERVER_HOSTNAME,
str_len,
HTTPc_FLAG_NONE,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
if (result == DEF_OK) {
printf("Connection to server succeeded.\n\r");
} else {
printf("Connection to server failed.\n\r");
}
/* ------------ SEND HTTP REQUEST ------------ */
str_len = Str_Len("/form");
result = HTTPc_ReqSend(p_conn,
p_req,
p_resp,
HTTP_METHOD_POST,
"/form",
str_len,
HTTPc_FLAG_NONE,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
if (result == DEF_OK) {
printf("%s\n\r", p_resp->ReasonPhrasePtr);
}
return (DEF_OK);
}
/*
*********************************************************************************************************
* HTTPcEx_ReqPrepareFormApp()
*
* Description : Example function to prepare the form table for an application type form
*
* Argument(s) : p_form_tbl Variable that will received the pointer to the form table.
*
* Return(s) : Number of fields in the table.
*********************************************************************************************************
*/
static CPU_INT08U HTTPcEx_ReqPrepareFormApp (HTTPc_FORM_TBL_FIELD **p_form_tbl)
{
HTTPc_FORM_TBL_FIELD *p_tbl;
HTTPc_KEY_VAL *p_kvp;
RTOS_ERR err;
p_tbl = &HTTPcEx_ReqFormTbl[0];
/* ---------- ADD FIRST FORM FIELD ----------- */
p_kvp = &HTTPcEx_KeyVal_Tbl[0];
p_kvp->KeyPtr = &HTTPcEx_KeyVal_KeyTbl[0][0];
p_kvp->ValPtr = &HTTPcEx_KeyVal_ValTbl[0][0];
p_kvp->KeyLen = Str_Len("Name");
p_kvp->ValLen = Str_Len("John Smith");
(void)Str_Copy_N(p_kvp->KeyPtr, "Name", p_kvp->KeyLen);
(void)Str_Copy_N(p_kvp->ValPtr, "Jonh Smith", p_kvp->ValLen);
HTTPc_FormAddKeyVal(p_tbl, p_kvp, &err);
/* ---------- ADD SECOND FORM FIELD ---------- */
p_tbl++;
p_kvp++;
p_kvp->KeyPtr = &HTTPcEx_KeyVal_KeyTbl[1][0];
p_kvp->ValPtr = &HTTPcEx_KeyVal_ValTbl[1][0];
p_kvp->KeyLen = Str_Len("Book");
p_kvp->ValLen = Str_Len("Implementing IPv6 Second Edition");
(void)Str_Copy_N(p_kvp->KeyPtr, "Book", p_kvp->KeyLen);
(void)Str_Copy_N(p_kvp->ValPtr, "Implementing IPv6 Second Edition", p_kvp->ValLen);
HTTPc_FormAddKeyVal(p_tbl, p_kvp, &err);
*p_form_tbl = &HTTPcEx_ReqFormTbl[0];
return (2);
}
HTTP Client Persistent Connection#
Persistent Connection allows you to send multiple HTTP requests one after another on the same opened connection before closing it. For more details, refer to section Persistent Connection .
Example#
In this example, two HTTP requests are queued on an HTTP Connection before the client closes the connection.
The function HTTPc_ReqSend() is called with the flag HTTPc_FLAG_REQ_NO_BLOCK, so the function is not blocking and will return before the transaction completes. Therefore the On Transaction Complete hook must be set to retrieve the HTTP response.
Listing - Persistent Connection Example Code#
#define HTTP_SERVER_HOSTNAME "www.example.com"
#define HTTPc_EX_CFG_CONN_NBR_MAX 5u
#define HTTPc_EX_CFG_REQ_NBR_MAX 5u
#define HTTPc_EX_CFG_BUF_SIZE 512u
HTTPc_CONN_OBJ HTTPcEx_ConnTbl[HTTPc_EX_CFG_CONN_NBR_MAX];
HTTPc_REQ_OBJ HTTPcEx_ReqTbl[HTTPc_EX_CFG_REQ_NBR_MAX];
HTTPc_RESP_OBJ HTTPcEx_RespTbl[HTTPc_EX_CFG_REQ_NBR_MAX];
CPU_CHAR HTTPcEx_BufTbl[HTTPc_EX_CFG_CONN_NBR_MAX][HTTPc_EX_CFG_BUF_SIZE ];
CPU_BOOLEAN close_conn = DEF_NO;
CPU_BOOLEAN req1_done = DEF_NO;
CPU_BOOLEAN req2_done = DEF_NO;
/*
*********************************************************************************************************
* HTTPcEx_ReqSendGET()
*
* Description : Example function to Send Requests on persistent connection.
*
* Argument(s) : None.
*
* Return(s) : DEF_YES, if request successfully sent.
* DEF_NO, otherwise.
*********************************************************************************************************
*/
CPU_BOOLEAN HTTPcEx_ReqSendGET (void)
{
HTTPc_CONN_OBJ *p_conn;
HTTPc_REQ_OBJ *p_req1;
HTTPc_REQ_OBJ *p_req2;
HTTPc_RESP_OBJ *p_resp1;
HTTPc_RESP_OBJ *p_resp2;
CPU_CHAR *p_buf;
CPU_BOOLEAN persistent;
CPU_BOOLEAN result;
RTOS_ERR err;
p_conn = &HTTPcEx_ConnTbl[0];
p_buf = &HTTPcEx_BufTbl[0][0];
p_req1 = &HTTPcEx_ReqTbl[0];
p_req2 = &HTTPcEx_ReqTbl[1];
p_resp1 = &HTTPcEx_RespTbl[0];
p_resp2 = &HTTPcEx_RespTbl[1];
/* ------------ INIT NEW CONNECTION ---------- */
HTTPc_ConnClr(p_conn, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ----------- SET PERSISTENT MODE ----------- */
persistent = DEF_YES;
HTTPc_ConnSetParam(p_conn,
HTTPc_PARAM_TYPE_PERSISTENT,
&persistent,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ---------- SET CONN'S CALLBACKS ----------- */
#if (HTTPc_CFG_MODE_ASYNC_TASK_EN == DEF_ENABLED)
HTTPc_ConnSetParam(p_conn,
HTTPc_PARAM_TYPE_CONN_CLOSE_CALLBACK,
&HTTPcEx_ConnCloseCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
#endif
/* ------------ INIT NEW REQUESTS ------------ */
HTTPc_ReqClr(p_req1, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
HTTPc_ReqClr(p_req2, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ---- SET REQ/RESP CALLBACK FUNCTIONS ------ */
#if (HTTPc_CFG_MODE_ASYNC_TASK_EN == DEF_ENABLED)
HTTPc_ReqSetParam(p_req1,
HTTPc_PARAM_TYPE_TRANS_COMPLETE_CALLBACK,
&HTTPcEx_TransDoneCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
HTTPc_ReqSetParam(p_req2,
HTTPc_PARAM_TYPE_TRANS_COMPLETE_CALLBACK,
&HTTPcEx_TransDoneCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
HTTPc_ReqSetParam(p_req1,
HTTPc_PARAM_TYPE_TRANS_ERR_CALLBACK,
&HTTPcEx_TransErrCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
HTTPc_ReqSetParam(p_req2,
HTTPc_PARAM_TYPE_TRANS_ERR_CALLBACK,
&HTTPcEx_TransErrCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
#endif
/* ------------ OPEN CONNECTION -------------- */
str_len = Str_Len(HTTP_SERVER_HOSTNAME);
result = HTTPc_ConnOpen(p_conn,
p_buf,
HTTPc_EX_CFG_BUF_SIZE,
HTTP_SERVER_HOSTNAME,
str_len,
HTTPc_FLAG_NONE,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
if (result == DEF_OK) {
printf("Connection to server succeeded.\n\r");
} else {
printf("Connection to server failed.\n\r");
}
/* ----------- SEND HTTP REQUESTS ------------ */
str_len = Str_Len("//");
result = HTTPc_ReqSend(p_conn,
p_req1,
p_resp1,
HTTP_METHOD_GET,
"//",
str_len,
HTTPc_FLAG_REQ_NO_BLOCK,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
(void)HTTPc_ReqSend(p_conn,
p_req2,
p_resp2,
HTTP_METHOD_GET,
"//",
str_len,
HTTPc_FLAG_REQ_NO_BLOCK,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
while (close_conn == DEF_NO)
{
/* Do OS delay. */
};
/* --------- CLOSE HTTP CONNECTION ----------- */
close_conn = DEF_NO;
HTTPc_ConnClose(p_conn, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
return (DEF_OK);
}
/*
*********************************************************************************************************
* HTTPcEx_TransDoneCallback()
*
* Description : Example callback function to be notified when an HTTP transaction is completed.
*
* Argument(s) : p_conn_obj Pointer to current HTTPc Connection object.
*
* p_req_obj Pointer to current HTTPc Request object.
*
* p_resp_obj Pointer to current HTTPc Response object.
*
* status Status of the HTTP transaction:
* DEF_OK, transaction succeeded.
* DEF_FAIL, transaction failed.
*
* Return(s) : None.
*********************************************************************************************************
*/
void HTTPcEx_TransDoneCallback (HTTPc_CONN_OBJ *p_conn_obj,
HTTPc_REQ_OBJ *p_req_obj,
HTTPc_RESP_OBJ *p_resp_obj,
CPU_BOOLEAN status)
{
HTTPc_REQ_OBJ *p_req1;
HTTPc_REQ_OBJ *p_req2;
p_req1 = &HTTPcEx_ReqTbl[0];
p_req2 = &HTTPcEx_ReqTbl[1];
if (p_req_obj == p_req1) {
if (status == DEF_OK) {
printf("Transaction #1: %s\n\r", p_resp_obj->ReasonPhrasePtr);
} else {
printf("Transaction #1 failed\n\r");
}
req1_done = DEF_YES;
} else if (p_req_obj == p_req2) {
if (status == DEF_OK) {
printf("Transaction #2: %s\n\r", p_resp_obj->ReasonPhrasePtr);
} else {
printf("Transaction #2 failed\n\r");
}
req2_done = DEF_YES;
} else {
printf("Unexpected error.\n\r");
}
close_conn = req1_done & req2_done;
}
HTTP Client Retrieve HTTP Response Data#
The HTTPc Response object will be filled by the HTTP Client stack with the fields below received in the HTTP response:
The Server HTTP version
Status Code
Reason phrase
Content type (if body present)
Content Length (if body present)
If the function HTTPc_ReqSend() was called in the blocking mode and the function returned with no errors, then the HTTPc Response object can be read by the application after the function call. Otherwise, the application must wait until the On Transaction Complete function is called by the HTTP Client stack to read the HTTPc Response object.
Two hook functions allow the application to retrieve more data from the HTTP response :
The first hook allows the application to retrieve header fields contained in the HTTP response. If the hook function is set via the function HTTPc_ReqSetParam() with the parameter type HTTPc_PARAM_TYPE_RESP_HDR_HOOK, the hook will be called by the HTTP Client module for each header field parsed and recognized by the stack. The application as therefore the liberty to copy the data received on its side inside the hook function.
The second hook allows the application to retrieve the data contained in the HTTP response body. If the hook function is set via the function HTTPc_ReqSetParam() with the parameter type HTTPc_PARAM_TYPE_RESP_BODY_HOOK, the hook will be called by the HTTP Client module for each piece of data received until all is received.
Examples#
Blocking Mode#
In the first example below, the function HTTPc_ReqSend() is called in blocking mode. Therefore, the HTTPc Response object can be read just after the function call.
Listing - Retrieve HTTP Response Data Example Code #1#
#define HTTP_SERVER_HOSTNAME "www.example.com"
#define HTTPc_EX_CFG_BUF_SIZE 1024
/*
*********************************************************************************************************
* HTTPcEx_ReqSendGET()
*
* Description : Example function to send a GET request and retrieve HTTP response.
*
* Argument(s) : None.
*
* Return(s) : DEF_OK, if HTTP transaction was successful.
* DEF_FAIL, otherwise.
*********************************************************************************************************
*/
CPU_BOOLEAN HTTPcEx_ReqSendGET (void)
{
HTTPc_CONN_OBJ conn;
HTTPc_REQ_OBJ req;
HTTPc_RESP_OBJ resp;
CPU_CHAR buf[HTTPc_EX_CFG_BUF_SIZE];
HTTPc_FLAGS flags;
CPU_SIZE_T str_len;
CPU_BOOLEAN result;
RTOS_ERR err;
/* ------------ INIT NEW CONNECTION ---------- */
HTTPc_ConnClr(&conn, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ----------- SET CONN'S CALLBACKS ---------- */
#if (HTTPc_CFG_MODE_ASYNC_TASK_EN == DEF_ENABLED)
HTTPc_ConnSetParam(&conn,
HTTPc_PARAM_TYPE_CONN_CLOSE_CALLBACK,
&HTTPcEx_ConnCloseCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
#endif
/* ------------- INIT NEW REQUEST ------------ */
HTTPc_ReqClr(&req, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* --------- SET TRANS HOOK FUNCTIONS -------- */
HTTPc_ReqSetParam(&req,
HTTPc_PARAM_TYPE_RESP_HDR_HOOK,
&HTTPcEx_RespHdrHook,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
HTTPc_ReqSetParam(&req,
HTTPc_PARAM_TYPE_RESP_BODY_HOOK,
&HTTPcEx_RespBodyHook,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ------ SET TRANS CALLBACK FUNCTIONS ------- */
#if (HTTPc_CFG_MODE_ASYNC_TASK_EN == DEF_ENABLED)
HTTPc_ReqSetParam(&req,
HTTPc_PARAM_TYPE_TRANS_ERR_CALLBACK,
&HTTPcEx_TransErrCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
#endif
/* ------------- OPEN CONNECTION ------------- */
str_len = Str_Len(HTTP_SERVER_HOSTNAME);
result = HTTPc_ConnOpen(&conn,
&buf,
HTTPc_EX_CFG_BUF_SIZE,
HTTP_SERVER_HOSTNAME,
str_len,
HTTPc_FLAG_NONE,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
if (result == DEF_OK) {
printf("Connection to server succeeded.\n\r");
} else {
printf("Connection to server failed.\n\r");
}
/* ------------ SEND HTTP REQUEST ------------ */
str_len = Str_Len("/");
result = HTTPc_ReqSend(&conn,
&req,
&resp,
HTTP_METHOD_GET,
"/",
str_len,
HTTPc_FLAG_NONE,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
if (result == DEF_OK) {
printf("%s\n\r", resp.ReasonPhrasePtr);
}
return (DEF_OK);
}
No-Blocking Mode#
In this second example, the function HTTPc_ReqSend() is called in non-blocking mode. Therefore, the HTTPc Response object can be read once the On Transaction Complete function is called.
Listing - Retrieve HTTP Response Data Example Code #2#
#define HTTP_SERVER_HOSTNAME "www.example.com"
#define HTTPc_EX_CFG_BUF_SIZE 1024
HTTPc_CONN_OBJ HTTPcEx_Conn;
HTTPc_REQ_OBJ HTTPcEx_Req;
HTTPc_RESP_OBJ HTTPcEx_Resp;
CPU_CHAR HTTPcEx_ConnBuf[HTTPc_EX_CFG_BUF_SIZE];
/*
*********************************************************************************************************
* HTTPcEx_ReqSendGET()
*
* Description : Example function to send a GET request and retrieve HTTP response.
*
* Argument(s) : None.
*
* Return(s) : DEF_OK, if HTTP transaction was successful.
* DEF_FAIL, otherwise.
*********************************************************************************************************
*/
CPU_BOOLEAN HTTPcEx_ReqSendGET (void)
{
HTTPc_CONN_OBJ *p_conn;
HTTPc_REQ_OBJ *p_req;
HTTPc_RESP_OBJ *p_resp;
CPU_CHAR *p_buf;
CPU_SIZE_T str_len;
CPU_BOOLEAN result;
HTTPc_ERR err;
p_conn = &HTTPcEx_Conn;
p_req = &HTTPcEx_Req;
p_resp = &HTTPcEx_Resp;
p_buf = &HTTPcEx_ConnBuf[0];
/* ------------ INIT NEW CONNECTION ---------- */
HTTPc_ConnClr(p_conn, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ----------- SET CONN'S CALLBACKS ---------- */
#if (HTTPc_CFG_MODE_ASYNC_TASK_EN == DEF_ENABLED)
HTTPc_ConnSetParam(p_conn,
HTTPc_PARAM_TYPE_CONN_CLOSE_CALLBACK,
&HTTPcEx_ConnCloseCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
#endif
/* ------------- INIT NEW REQUEST ------------ */
HTTPc_ReqClr(p_req, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* --------- SET TRANS HOOK FUNCTIONS -------- */
HTTPc_ReqSetParam(p_req,
HTTPc_PARAM_TYPE_RESP_HDR_HOOK,
&HTTPcEx_RespHdrHook,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
HTTPc_ReqSetParam(p_req,
HTTPc_PARAM_TYPE_RESP_BODY_HOOK,
&HTTPcEx_RespBodyHook,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ------ SET TRANS CALLBACK FUNCTIONS ------- */
#if (HTTPc_CFG_MODE_ASYNC_TASK_EN == DEF_ENABLED)
HTTPc_ReqSetParam(p_req,
HTTPc_PARAM_TYPE_TRANS_COMPLETE_CALLBACK,
&HTTPcEx_TransDoneCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
HTTPc_ReqSetParam(p_req,
HTTPc_PARAM_TYPE_TRANS_ERR_CALLBACK,
&HTTPcEx_TransErrCallback,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
#endif
/* ------------- OPEN CONNECTION ------------- */
str_len = Str_Len(HTTP_SERVER_HOSTNAME);
result = HTTPc_ConnOpen(p_conn,
p_buf,
HTTPc_EX_CFG_BUF_SIZE,
HTTP_SERVER_HOSTNAME,
str_len,
HTTPc_FLAG_NONE,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
if (result == DEF_OK) {
printf("Connection to server succeeded.\n\r");
} else {
printf("Connection to server failed.\n\r");
}
/* ------------ SEND HTTP REQUEST ------------ */
str_len = Str_Len("/");
result = HTTPc_ReqSend(p_conn,
p_req,
p_resp,
HTTP_METHOD_GET,
"/",
str_len,
HTTPc_FLAG_REQ_NO_BLOCK,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
return (DEF_OK);
}
/*
*********************************************************************************************************
* HTTPcEx_TransDoneCallback()
*
* Description : Example callback function to be notified when an HTTP transaction was completed.
*
* Once this callback is called, the HTTPc Response object is ready to be read by the application
* if no error occurred.
*
* Argument(s) : p_conn Pointer to current HTTPc Connection object.
*
* p_req Pointer to current HTTPc Request object.
*
* p_resp Pointer to current HTTPc Response object.
*
* status DEF_OK, if transaction was complete successfully.
* DEF_NO, otherwise.
*
* Return(s) : None.
*********************************************************************************************************
*/
static void HTTPcEx_TransDoneCallback(HTTPc_CONN_OBJ *p_conn,
HTTPc_REQ_OBJ *p_req,
HTTPc_RESP_OBJ *p_resp,
CPU_BOOLEAN status)
{
if (status == DEF_OK) {
printf("Transaction response status: %s\n\r", p_resp->ReasonPhrasePtr);
} else {
printf("Transaction failed\n\r");
}
}
Response Header and Body Hook Functions#
The example code below is an implementation of the On Response Header hook function and the On Response Body hook function.
Listing - Response Hook Functions Example Code#
#define HTTPc_EX_CFG_HDR_VAL_BUF_LEN 100
CPU_CHAR HTTPcEx_HdrValBuf[HTTPc_EX_CFG_HDR_VAL_BUF_LEN];
/*
*********************************************************************************************************
* HTTPcEx_RespHdrHook()
*
* Description : Example hook function to retrieve Header Fields received in the HTTP response.
*
* Argument(s) : p_conn Pointer to current HTTPc Connection object.
*
* p_req Pointer to current HTTPc Request object.
*
* hdr_field Header field type received.
*
* p_hdr_val Pointer to Header field value string received.
*
* val_len Length of value string.
*
* Return(s) : None.
*********************************************************************************************************
*/
static void HTTPcEx_RespHdrHook(HTTPc_CONN_OBJ *p_conn,
HTTPc_REQ_OBJ *p_req,
HTTP_HDR_FIELD hdr_field,
CPU_CHAR *p_hdr_val,
CPU_INT16U val_len)
{
CPU_CHAR *p_buf;
CPU_INT16U len;
p_buf = &HTTPcEx_HdrValBuf[0];
switch (hdr_field) {
case HTTP_HDR_FIELD_DATE:
case HTTP_HDR_FIELD_SERVER:
len = DEF_MIN((HTTPc_EX_CFG_HDR_VAL_BUF_LEN - 1), val_len);
Mem_Copy(p_buf, p_hdr_val, len);
p_buf += len;
*p_buf = '\0';
break;
default:
break;
}
}
/*
*********************************************************************************************************
* HTTPcEx_RespBodyHook()
*
* Description : Example hook function to retrieve body data.
*
* In this example, a html file is received and is copied into a file.
*
* Argument(s) : p_conn Pointer to current HTTPc Connection object.
*
* p_req Pointer to current HTTPc Request object.
*
* content_type Content type of the body received in the HTTP response.
*
* p_data Pointer to the data piece received.
*
* data_len Length of data piece received.
*
* last_chunk DEF_YES, if this represent the last piece of the data body to receive.
* DEF_NO, if data still remains to be received.
*
* Return(s) : None.
*********************************************************************************************************
*/
static void HTTPcEx_RespBodyHook (HTTPc_CONN_OBJ *p_conn,
HTTPc_REQ_OBJ *p_req,
HTTP_CONTENT_TYPE content_type,
void *p_data,
CPU_INT32U data_len,
CPU_BOOLEAN last_chunk)
{
FS_FILE_HANDLE file_handle;
CPU_SIZE_T size_wr;
CPU_SIZE_T size_wr_tot;
CPU_BOOLEAN is_open;
RTOS_ERR err;
file_handle = FSFile_Open(FSWrkDir_NullHandle,
"ram0/index.html",
(FS_FILE_ACCESS_MODE_WR | FS_FILE_ACCESS_MODE_CREATE | FS_FILE_ACCESS_MODE_APPEND),
&err);
if (err.Code != RTOS_ERR_NONE) {
return;
}
switch (content_type) {
case HTTP_CONTENT_TYPE_HTML:
if (p_data != DEF_NULL) {
size_wr = 0u;
size_wr_tot = 0u;
while (size_wr < data_len) {
size_wr = FSFile_Wr(file_handle,
p_data,
data_len,
&err);
if (err.Code != RTOS_ERR_NONE) {
return;
}
size_wr_tot += size_wr;
}
}
break;
case HTTP_CONTENT_TYPE_OCTET_STREAM:
case HTTP_CONTENT_TYPE_PDF:
case HTTP_CONTENT_TYPE_ZIP:
case HTTP_CONTENT_TYPE_GIF:
case HTTP_CONTENT_TYPE_JPEG:
case HTTP_CONTENT_TYPE_PNG:
case HTTP_CONTENT_TYPE_JS:
case HTTP_CONTENT_TYPE_PLAIN:
case HTTP_CONTENT_TYPE_CSS:
case HTTP_CONTENT_TYPE_JSON:
default:
break;
}
FSFile_Close(file_handle, &err);
}
HTTP Client WebSocket#
WebSocket allows to create a full duplex communication channel over a single TCP/HTTP connection and enables streams of structured messages. It use simple and efficient headers to describe those messages which offer a better solution when it come to send small data at higher rate. For more details, refer to section WebSocket .
This section regroups topics to help developing a custom WebSocket application with the HTTP Client module. Examples are include in many sub-sections.
HTTP Client Upgrading an HTTP Connection#
Because it uses many HTTP functionalities for opening handshake, the WebSocket protocol has been integrated has part of Micrium OS HTTP Client module. Furthermore, all the HTTP Client request features, such as query string, are available during the opening handshake request. Here are the usual steps to upgrade a HTTP connection to WebSocket:
First, create a HTTPc Connection to the desired server using HTTPc_ConnOpen(). If successful, it will return a valid HTTPc_CONN_OBJ object that can be used for the next request.
Before sending an Upgrade Request to the server, an HTTPc_WEBSOCK_OBJ object may be configured by using HTTPc_WebSockSetParam() function. Note that WebSocket Message Reception is done through hook functions that are configured in HTTPc_WEBSOCK_OBJ object passed during the WebSocket Upgrade.
Because the WebSocket opening handshake is essentially a specific HTTP Request with specific headers, HTTPc_WebSockUpgrade() function is available to simplify the connection upgrade. It will automatically set the mandatory headers and validates the response from the server. Because it also uses a HTTPc_REQ_OBJ object, you can use all the features available during a normal HTTP Request.
Finally, when the opening handshake is successful, the connection that has been established in step 1 has now upgraded to WebSocket and is no more related to HTTP. At this point, HTTPc_WebSockSend() can be used for WebSocket Message Transmission and the WebSocket Message Reception will be processed through the RX hook configured in HTTPc_WEBSOCK_OBJ.
Related Hooks
Name | Description | Object | Parameter Type |
---|---|---|---|
Called when a WebSocket Upgrade is successful. | HTTPc_WEBSOCK_OBJ | HTTPc_PARAM_TYPE_WEBSOCK_ON_OPEN | |
Called when a connection that has been successfully upgraded close. | HTTPc_WEBSOCK_OBJ | HTTPc_PARAM_TYPE_WEBSOCK_ON_CLOSE |
Example#
The following example simply shows how to upgrade an HTTP connection to Websocket. As you can see below, it will first open an HTTP connection to the remote server and then upgrade it. Note that there's no Message Reception mechanism configured in this example.
Listing - Upgrading an HTTP Connection#
#include <rtos/net/include/http_client.h>
/*
*********************************************************************************************************
* LOCAL DEFINES
*********************************************************************************************************
*/
#define HTTPc_EXAMPLE_URI "server.example.com"
#define HTTPc_EXAMPLE_RESSOURCE "/echo"
#define HTTPc_EXAMPLE_CONN_BUF_LEN 1024
/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/
static HTTPc_CONN_OBJ HTTPcExample_Conn;
static CPU_CHAR HTTPcExample_ConnBuf[HTTPc_EXAMPLE_CONN_BUF_LEN];
static HTTPc_REQ_OBJ HTTPcExample_Req;
static HTTPc_RESP_OBJ HTTPcExample_Resp;
static HTTPc_WEBSOCK_OBJ HTTPcExample_WebSock;
/*
*********************************************************************************************************
* LOCAL FUNCTION PROTOTYPES
*********************************************************************************************************
*/
static void HTTPcExample_ConnOnClose (HTTPc_CONN_OBJ *p_conn,
HTTPc_CONN_CLOSE_STATUS close_status,
HTTPc_ERR err);
static void HTTPcExample_WebSockOnOpen (HTTPc_CONN_OBJ *p_conn);
static void HTTPcExample_WebSockOnClose (HTTPc_CONN_OBJ *p_conn,
HTTPc_WEBSOCK_CLOSE_CODE close_code,
HTTPc_WEBSOCK_CLOSE_REASON *p_reason) ;
/*
*********************************************************************************************************
* EXAMPLE
*********************************************************************************************************
*/
CPU_BOOLEAN HTTPcExample_OpenWebSocket (void)
{
CPU_BOOLEAN result;
RTOS_ERR err;
/* ----------- INIT NEW CONNECTION & REQUEST ----- */
/* Always Clear the object. */
HTTPc_ConnClr(&HTTPcExample_Conn, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
HTTPc_ReqClr(&HTTPcExample_Req, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
HTTPc_WebSockClr(&HTTPcExample_WebSock, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ------------- SET ON CONNECTION CLOSE --------- */
/* This callback is always required. */
HTTPc_ConnSetParam( &HTTPcExample_Conn,
HTTPc_PARAM_TYPE_CONN_CLOSE_CALLBACK,
(void *) HTTPcExample_ConnOnClose,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ----------------- OPEN CONNECTION ------------- */
result = HTTPc_ConnOpen(&HTTPcExample_Conn,
HTTPcExample_ConnBuf,
HTTPc_EXAMPLE_CONN_BUF_LEN,
HTTPc_EXAMPLE_URI,
sizeof(HTTPc_EXAMPLE_URI),
HTTPc_FLAG_NONE,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* --------------- SET WEBSOCK ON OPEN ----------- */
HTTPc_WebSockSetParam( &HTTPcExample_WebSock,
HTTPc_PARAM_TYPE_WEBSOCK_ON_OPEN,
(void *) HTTPcExample_WebSockOnOpen,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* --------------- SET WEBSOCK ON CLOSE ---------- */
HTTPc_WebSockSetParam( &HTTPcExample_WebSock,
HTTPc_PARAM_TYPE_WEBSOCK_ON_CLOSE,
(void *) HTTPcExample_WebSockOnClose,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ------- UPGRADE HTTP CONNECTION TO WEBSOCKET -- */
result = HTTPc_WebSockUpgrade(&HTTPcExample_Conn,
&HTTPcExample_Req,
&HTTPcExample_Resp,
&HTTPcExample_WebSock,
HTTPc_EXAMPLE_RESSOURCE,
sizeof(HTTPc_EXAMPLE_RESSOURCE),
HTTPc_FLAG_NONE,
&err);
if (result != DEF_OK) {
return (DEF_FAIL);
}
return (DEF_OK);
}
/*
*********************************************************************************************************
* CONNECTION ON CLOSE CALLBACK
*********************************************************************************************************
*/
static void HTTPcExample_ConnOnClose (HTTPc_CONN_OBJ *p_conn,
HTTPc_CONN_CLOSE_STATUS close_status,
RTOS_ERR err)
{
/* Called when a connection closes. */
}
/*
*********************************************************************************************************
* WEBSOCK ON OPEN CALLBACK
*********************************************************************************************************
*/
static void HTTPcExample_WebSockOnOpen (HTTPc_CONN_OBJ *p_conn)
{
/* Called when a WebSocket Upgrade is successful. */
}
/*
*********************************************************************************************************
* WEBSOCK ON CLOSE CALLBACK
*********************************************************************************************************
*/
static void HTTPcExample_WebSockOnClose (HTTPc_CONN_OBJ *p_conn,
HTTPc_WEBSOCK_CLOSE_CODE close_code,
HTTPc_WEBSOCK_CLOSE_REASON *p_reason)
{
/* Called when a WebSocket Connection has closed. */
}
HTTP Client Message reception#
In the WebSocket Protocol, data is exchanged using sequences of frame to form WebSocket Messages. The user doesn't need to know how the WebSocket data framing works since the HTTP Client WebSocket module manages it internally. The HTTP Client WebSocket API simplifies the application development by using the concept of message which can be summarized by its Type, Payload Length and Contents.
WebSocket Messages can have 5 different types divided in 2 groups.
Control Message
Close
Ping
Pong
Data Message
Text
Binary
Control Message#
Control messages are intended to be used for protocol-level signaling. Note that their payload length cannot exceed 125 bytes and they cannot be fragmented (only one frame per message).
Since control messages are protocol related, they are managed directly by the WebSocket Module which provides hook to notify the application.
Message Type | WebSocket Module Behavior |
---|---|
Close | When a Close message is received from the remote server, the WebSocket module will start the closing handshake. Once it's done, successfully or not, it will call the hook On Close |
Ping | When a Ping message is received from the remote server, the WebSocket module will reply the correct Pong message. The application won't be notify. |
Pong | When a Pong message is received from the remote server, the WebSocket module will simply call the hook On Pong . |
Data Messages#
Data messages are intended to transport information. Their length can vary from 0 to 2^64 and can be fragmented. They can be divided in two type.
Message Type | |
---|---|
Text | The content must respected UTF-8 standard. |
Binary | The content is not restricted. |
Note that the HTTP Client WebSocket module doesn't validate UTF-8 and must be done by the user application if necessary.
The reception of any Data Messages are done through hooks that are configured in the HTTPc_WEBSOCK_OBJ and that must be set before the connection upgrade request ( HTTPc_WebSockUpgrade() ).
Name | Description | Object | Parameter Type |
---|---|---|---|
Called at the beginning of the WebSocket Data Type message reception. | HTTPc_WEBSOCK_OBJ | HTTPc_PARAM_TYPE_WEBSOCK_ON_MSG_RX_INIT | |
Called each time a chunk of the message is received is available. | HTTPc_WEBSOCK_OBJ | HTTPc_PARAM_TYPE_WEBSOCK_ON_MSG_RX_DATA | |
Called when the Data message is completely received. | HTTPc_WEBSOCK_OBJ | HTTPc_PARAM_TYPE_WEBSOCK_ON_MSG_RX_COMPLETE |
Note that only one Data Message is processed at a time.
Data Message Reception Mode#
The hooks described in the previous section can be use in many different ways. However, those can be group in two different mode.
Normal mode#
Normal Mode uses all of the three Data Message Reception hooks. It allow the user to be notify every time a message payload chunk is available with the On Message RX Data hook. Thus, the application can parse a message during its reception without having to copying it all in a buffer.
This mode is useful when the memory footprints is critical and the message length can be long or undefined.
Auto mode#
Auto Mode only use two hooks. During On Message Reception Initialization , it is possible to set a pointer to the buffer where the message payload must be set. If the application do so, the message will be automatically copied to the specified buffer. Once the message is completely received, On Message RX Complete hook will be called and data will be available is the buffer previously set.
This mode is useful for simpler application which the message length received from other endpoint are small and size-limited
HTTP Client Auto Mode Example#
This example shows how to open a WebSocket with Data message Reception hooks configured in Auto Mode.
Listing - HTTP Client Auto Mode#
/*
*********************************************************************************************************
* LOCAL DEFINES
*********************************************************************************************************
*/
#define HTTPc_EXAMPLE_URI "server.example.com"
#define HTTPc_EXAMPLE_RESSOURCE "/echo"
#define HTTPc_EXAMPLE_CONN_BUF_LEN 1024
#define HTTPc_EXAMPLE_MSG_MAX_LEN 512
/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/
static HTTPc_CONN_OBJ HTTPcExample_Conn;
static CPU_CHAR HTTPcExample_ConnBuf[HTTPc_EXAMPLE_CONN_BUF_LEN];
static HTTPc_REQ_OBJ HTTPcExample_Req;
static HTTPc_RESP_OBJ HTTPcExample_Resp;
static HTTPc_WEBSOCK_OBJ HTTPcExample_WebSock;
static CPU_CHAR HTTPcExample_RxBuf[HTTPc_EXAMPLE_MSG_MAX_LEN];
/*
*********************************************************************************************************
* LOCAL FUNCTION PROTOTYPES
*********************************************************************************************************
*/
static void HTTPcExample_ConnOnClose (HTTPc_CONN_OBJ *p_conn,
HTTPc_CONN_CLOSE_STATUS close_status,
HTTPc_ERR err);
static void HTTPcExample_WebSockOnMsgRxInit (HTTPc_CONN_OBJ *p_conn,
HTTPc_WEBSOCK_MSG_TYPE msg_type,
CPU_INT32U msg_len,
void **p_data);
static void HTTPcExample_WebSockOnMsgRxComplete (HTTPc_CONN_OBJ *p_conn);
/*
*********************************************************************************************************
* EXAMPLE
*********************************************************************************************************
*/
CPU_BOOLEAN HTTPcExample_OpenWebSocket (void)
{
CPU_BOOLEAN result;
RTOS_ERR err;
/* ----------- INIT NEW CONNECTION & REQUEST ---------- */
/* Always Clear the object. */
HTTPc_ConnClr(&HTTPcExample_Conn, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
HTTPc_ReqClr(&HTTPcExample_Req, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
HTTPc_WebSockClr(&HTTPcExample_WebSock, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ------------- SET ON CONNECTION CLOSE -------------- */
/* This callback is always required. */
HTTPc_ConnSetParam( &HTTPcExample_Conn,
HTTPc_PARAM_TYPE_CONN_CLOSE_CALLBACK,
(void *) HTTPcExample_ConnOnClose,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ----------------- OPEN CONNECTION ------------------ */
result = HTTPc_ConnOpen(&HTTPcExample_Conn,
HTTPcExample_ConnBuf,
HTTPc_EXAMPLE_CONN_BUF_LEN,
HTTPc_EXAMPLE_URI,
sizeof(HTTPc_EXAMPLE_URI),
HTTPc_FLAG_NONE,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ----------- SET WEBSOCK HOOKS/CALLBACKS ------------ */
/* Set OnMsgRxInit hooks. */
HTTPc_WebSockSetParam( &HTTPcExample_WebSock,
HTTPc_PARAM_TYPE_WEBSOCK_ON_MSG_RX_INIT,
(void *) HTTPcExample_WebSockOnMsgRxInit,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* Set OnMsgRxComplete hooks. */
HTTPc_WebSockSetParam( &HTTPcExample_WebSock,
HTTPc_PARAM_TYPE_WEBSOCK_ON_MSG_RX_COMPLETE,
(void *) HTTPcExample_WebSockOnMsgRxComplete,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ------- UPGRADE HTTP CONNECTION TO WEBSOCKET ------- */
result = HTTPc_WebSockUpgrade(&HTTPcExample_Conn,
&HTTPcExample_Req,
&HTTPcExample_Resp,
&HTTPcExample_WebSock,
HTTPc_EXAMPLE_RESSOURCE,
sizeof(HTTPc_EXAMPLE_RESSOURCE),
HTTPc_FLAG_NONE,
&err);
if (result != DEF_OK) {
return (DEF_FAIL);
}
return (DEF_OK);
}
/*
*********************************************************************************************************
* CONNECTION ON CLOSE CALLBACK
*********************************************************************************************************
*/
static void HTTPcExample_ConnOnClose (HTTPc_CONN_OBJ *p_conn,
HTTPc_CONN_CLOSE_STATUS close_status,
HTTPc_ERR err)
{
/* Called when a connection close. */
}
/*
*********************************************************************************************************
* WEBSOCK ON MSG RX INIT HOOK
*********************************************************************************************************
*/
static void HTTPcExample_WebSockOnMsgRxInit (HTTPc_CONN_OBJ *p_conn,
HTTPc_WEBSOCK_MSG_TYPE msg_type,
CPU_INT32U msg_len,
void **p_data)
{
/* Validate that we have enough space in the buffer... */
/* ...to get all the message. */
if (msg_len <= HTTPc_EXAMPLE_MSG_MAX_LEN) {
*p_data = HTTPcExample_RxBuf; /* Set the pointer where the message data must be set. */
}
}
/*
*********************************************************************************************************
* WEBSOCK ON MSG RX COMPLETE HOOK
*********************************************************************************************************
*/
static void HTTPcExample_WebSockOnMsgRxComplete (HTTPc_CONN_OBJ *p_conn)
{
/* Once the message is completely received... */
/* ...Do Something. */
}
HTTP Client Normal Mode Example#
This example show how to open a WebSocket with Data message Reception hooks configured in Normal Mode.
Listing - HTTP Client Normal Mode#
#include <rtos/net/include/http_client.h>
/*
*********************************************************************************************************
* LOCAL DEFINES
*********************************************************************************************************
*/
#define HTTPc_EXAMPLE_URI "server.example.com"
#define HTTPc_EXAMPLE_RESSOURCE "/echo"
#define HTTPc_EXAMPLE_CONN_BUF_LEN 1024
#define HTTPc_EXAMPLE_MSG_MAX_LEN 512
/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/
static HTTPc_CONN_OBJ HTTPcExample_Conn;
static CPU_CHAR HTTPcExample_ConnBuf[HTTPc_EXAMPLE_CONN_BUF_LEN];
static HTTPc_REQ_OBJ HTTPcExample_Req;
static HTTPc_RESP_OBJ HTTPcExample_Resp;
static HTTPc_WEBSOCK_OBJ HTTPcExample_WebSock;
static CPU_CHAR HTTPcExample_RxBuf[HTTPc_EXAMPLE_MSG_MAX_LEN];
static CPU_INT32U HTTPcExample_RxMsgLenToGet ;
/*
*********************************************************************************************************
* LOCAL FUNCTION PROTOTYPES
*********************************************************************************************************
*/
static void HTTPcExample_ConnOnClose (HTTPc_CONN_OBJ *p_conn,
HTTPc_CONN_CLOSE_STATUS close_status,
HTTPc_ERR err);
static void HTTPcExample_WebSockOnMsgRxInit (HTTPc_CONN_OBJ *p_conn,
HTTPc_WEBSOCK_MSG_TYPE msg_type,
CPU_INT32U msg_len,
void **p_data);
static CPU_INT32U HTTPcExample_WebSockOnMsgRxData (HTTPc_CONN_OBJ *p_conn,
HTTPc_WEBSOCK_MSG_TYPE msg_type,
void *p_data,
CPU_INT16U data_len);
static void HTTPcExample_WebSockOnMsgRxComplete (HTTPc_CONN_OBJ *p_conn);
/*
*********************************************************************************************************
* EXAMPLE
*********************************************************************************************************
*/
CPU_BOOLEAN HTTPcExample_OpenWebSocket (void)
{
CPU_BOOLEAN result;
RTOS_ERR err;
/* ----------- INIT NEW CONNECTION & REQUEST ---------- */
/* Always Clear the object. */
HTTPc_ConnClr(&HTTPcExample_Conn, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
HTTPc_ReqClr(&HTTPcExample_Req, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
HTTPc_WebSockClr(&HTTPcExample_WebSock, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ------------- SET ON CONNECTION CLOSE -------------- */
/* This callback is always required. */
HTTPc_ConnSetParam( &HTTPcExample_Conn,
HTTPc_PARAM_TYPE_CONN_CLOSE_CALLBACK,
(void *) HTTPcExample_ConnOnClose,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ----------------- OPEN CONNECTION ------------------ */
result = HTTPc_ConnOpen(&HTTPcExample_Conn,
HTTPcExample_ConnBuf,
HTTPc_EXAMPLE_CONN_BUF_LEN,
HTTPc_EXAMPLE_URI,
sizeof(HTTPc_EXAMPLE_URI),
HTTPc_FLAG_NONE,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ----------- SET WEBSOCK HOOKS/CALLBACKS ------------ */
/* Set OnMsgRxInit hooks. */
HTTPc_WebSockSetParam( &HTTPcExample_WebSock,
HTTPc_PARAM_TYPE_WEBSOCK_ON_MSG_RX_INIT,
(void *) HTTPcExample_WebSockOnMsgRxInit,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* Set OnMsgRxData hooks. */
HTTPc_WebSockSetParam( &HTTPcExample_WebSock,
HTTPc_PARAM_TYPE_WEBSOCK_ON_MSG_RX_DATA,
(void *) HTTPcExample_WebSockOnMsgRxData,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* Set OnMsgRxComplete hooks. */
HTTPc_WebSockSetParam( &HTTPcExample_WebSock,
HTTPc_PARAM_TYPE_WEBSOCK_ON_MSG_RX_COMPLETE,
(void *) HTTPcExample_WebSockOnMsgRxComplete,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* ------- UPGRADE HTTP CONNECTION TO WEBSOCKET ------- */
result = HTTPc_WebSockUpgrade(&HTTPcExample_Conn,
&HTTPcExample_Req,
&HTTPcExample_Resp,
&HTTPcExample_WebSock,
HTTPc_EXAMPLE_RESSOURCE,
sizeof(HTTPc_EXAMPLE_RESSOURCE),
HTTPc_FLAG_NONE,
&err);
if (result != DEF_OK) {
return (DEF_FAIL);
}
return (DEF_OK);
}
/*
*********************************************************************************************************
* CONNECTION ON CLOSE CALLBACK
*********************************************************************************************************
*/
static void HTTPcExample_ConnOnClose (HTTPc_CONN_OBJ *p_conn,
HTTPc_CONN_CLOSE_STATUS close_status,
HTTPc_ERR err)
{
/* Called when a connection close. */
}
/*
*********************************************************************************************************
* WEBSOCK ON MSG RX INIT HOOK
*********************************************************************************************************
*/
static void HTTPcExample_WebSockOnMsgRxInit (HTTPc_CONN_OBJ *p_conn,
HTTPc_WEBSOCK_MSG_TYPE msg_type,
CPU_INT32U msg_len,
void **p_data)
{
/* Validate that we have enough space in the buffer... */
/* ...to get all the message. */
if (msg_len <= HTTPc_EXAMPLE_MSG_MAX_LEN) {
HTTPcExample_RxMsgLenToGet = msg_len;
} else {
HTTPcExample_RxMsgLenToGet = 0u;
}
}
/*
*********************************************************************************************************
* WEBSOCK ON MSG RX DATA HOOK
*********************************************************************************************************
*/
static CPU_INT32U HTTPcExample_WebSockOnMsgRxData (HTTPc_CONN_OBJ *p_conn,
HTTPc_WEBSOCK_MSG_TYPE msg_type,
void *p_data,
CPU_INT16U data_len)
{
CPU_INT16U data_len_used;
data_len_used = 0u;
if (HTTPcExample_RxMsgLenToGet != 0u) {
if (HTTPcExample_RxMsgLenToGet == data_len) {
/* In this example, wait to have all the message... */
/* ...before copying it in the reception buffer. */
Mem_Copy(HTTPcExample_RxBuf, p_data, data_len);
HTTPcExample_RxMsgLenToGet = 0u;
data_len_used = data_len;
}
}
return (data_len_used); /* Return that number of bytes used. */
}
/*
*********************************************************************************************************
* WEBSOCK ON MSG _RX COMLETE HOOK
*********************************************************************************************************
*/
static void HTTPcExample_WebSockOnMsgRxComplete (HTTPc_CONN_OBJ *p_conn)
{
/* Once the message is completely received... */
/* ...Do Something. */
}
HTTP Client Sending Message#
The user can send a WebSocket message with HTTPc_WebSockSend() function and a properly initialized HTTPc_WEBSOCK_MSG_OBJ. To set the type, the payload content and length of a message, it is possible to either configure it with HTTPc_WebSockSend() parameters or with hooks configured for each message.
For message transmission, it's possible to send all the message type available :
HTTPc_WEBSOCK_MSG_TYPE_TXT
HTTPc_WEBSOCK_MSG_TYPE_BIN
HTTPc_WEBSOCK_MSG_TYPE_CLOSE
HTTPc_WEBSOCK_MSG_TYPE_PING
HTTPc_WEBSOCK_MSG_TYPE_PONG
Here a list of the available Transmission hooks.
Name | Description | Object | Parameter Type |
---|---|---|---|
Called when the message is ready to be sent. | HTTPc_WEBSOCK_OBJ | HTTPc_PARAM_TYPE_WEBSOCK_ON_MSG_TX_INIT | |
Called to set the internal connection buffer of a data chunk of a message to send. | HTTPc_WEBSOCK_OBJ | HTTPc_PARAM_TYPE_WEBSOCK_ON_MSG_TX_DATA | |
Called when the message is completely transmitted. | HTTPc_WEBSOCK_OBJ | HTTPc_PARAM_TYPE_WEBSOCK_ON_MSG_TX_COMPLETE |
Transmission Mode#
The hooks described in the previous section can be use in many different ways. However, those can be group in three different mode.
Mode | Buffer used | Message Length | On Message TX Initialization | On Message TX Data | On Message TX Complete |
---|---|---|---|---|---|
Normal | External data buffer set when HTTPc_WebSockSend() is called. | Defined at the beginning when HTTPc_WebSockSend() is called. | Not Used | Not Used | Optional |
Hooks | Internal Connection data buffer is used to construct message to transmit. | Defined either when HTTPc_WebSockSend() is called or with On Message TX Initialization hook. | Optional | Used | Optional |
Dynamic | Internal Connection data buffer is used to construct message to transmit. | Defined either when HTTPc_WebSockSend() is called or with On Message TX Initialization hook and must be HTTPc_WEBSOCK_TX_MSG_LEN_NOT_DEFINED. | Optional | Used | Optional |
Normal Mode#
Normal mode only uses only HTTPc_WebSockSend() and doesn't require a hook. The application must provide a pointer to the message payload data and its length that will be used during the transmission.
This mode is simple to use and suitable for a non-complex application.
Hook Mode#
Hook mode allows you to use directly the connection buffer to send a message using hooks.
The application must provide the length of the message at the beginning either with HTTPc_WebSockSend() or with the On Message TX Initialization hook.
Then, On Message TX Data is called and provide the application a pointer to the internal connection buffer and the available length.
Once the application has set the buffer, it must return the total number of bytes used in this buffer.
On Message TX Data is called until the message is completely sent, thus the length set at the beginning matches the total length sent.
This mode allows you to save memory space by using directly the connection buffer. However, the message length must be known at the beginning.
Dynamic Mode#
Dynamic mode use the message fragmentation mechanism that the WebSocket protocol provides to transfer message. It allows to send a message without knowing the total message and to use directly the connection buffer to construct the message to send, thereby reducing the memory footprints.
To use this mode, two points are important:
The length of the message must be set to HTTPc_WEBSOCK_TX_MSG_LEN_NOT_DEFINED. It possible to either set it during HTTPc_WebSockSend() is called or using the On Message TX Initialization hook.
Then, On Message TX Data is called and provide the application a pointer to the internal connection buffer and the available length.
Each time the On Message TX Data is called, the application must set the buffer and return the numbers of bytes to be sent.
To complete the message, 0 value must be returned from this function.
This mode helps saving memory space by using directly the connection buffer to construct messages and allows to start the data transmission without knowing the total message length.
Note that it is not possible to send Control Message (Close, Ping or Pong) in Dynamic Mode. Those messages must be sent either in Hook Mode or Normal Mode. |
---|
Non-Blocking Option#
An non-blocking option is available when HTTPc_WebSockSend() is called by using the flag HTTPc_FLAG_WEBSOCK_NO_BLOCK. If used, On Message TX Complete hook must be set. It allows to queue message without having to wait the completion of each message transmission.
HTTP Client Closing a Connection#
WebSockets can be closed properly by sending a Close Message. Close Messages have a special format which the first 2 bytes is the close code defined by the standard. The rest of the data concatenated is usually defined by the user for debug purpose. When the other end receive the close message, it should reply with the exact same message. However, it is possible that endpoints don't agree on the value of the close code, but the connection will be closed when both have received and transmitted a Close Messages.
Closing messages are sent in the same way that other message are sent using HTTPc_WebSockSend() (see Sending Message ). Note that Control message payload length cannot exceed 125 bytes and cannot be sent in Dynamic Mode. Once the closing handshake is done, the WebSocket Module will notify the application if the On Close hook is properly set.
Finally, HTTPc_WebSockFmtCloseMsg() allows the user to properly format a Close Message into a buffer before sending it.
HTTP Client Protocol Recognized Fields#
This section regroups lists of all the HTTP fields recognized by Micrium OS HTTP Client module.
HTTP Versions#
HTTP Version | Micrium Type |
---|---|
0.9 | HTTP_PROTOCOL_VER_0_9 |
1.0 | HTTP_PROTOCOL_VER_1_0 |
1.1 | HTTP_PROTOCOL_VER_1_1 |
HTTP Methods#
HTTP Method | Micrium Type |
---|---|
CONNECT | HTTP_METHOD_CONNECT |
DELETE | HTTP_METHOD_DELETE |
GET | HTTP_METHOD_GET |
HEAD | HTTP_METHOD_HEAD |
OPTIONS | HTTP_METHOD_OPTIONS |
POST | HTTP_METHOD_POST |
PUT | HTTP_METHOD_PUT |
TRACE | HTTP_METHOD_TRACE |
Those are the methods recognized by the HTTP Server and Client stacks. It doesn't mean that all those methods are supported. |
---|
HTTP Header Fields#
Header Field Type | Micrium Type |
---|---|
Content-Type | HTTP_HDR_FIELD_CONTENT_TYPE |
Content-Length | HTTP_HDR_FIELD_CONTENT_LEN |
Content-Disposition | HTTP_HDR_FILED_CONTENT_DISPOSITION |
Host | HTTP_HDR_FIELD_HOST |
Location | HTTP_HDR_FIELD_LOCATION |
Connection | HTTP_HDR_FIELD_CONN |
Transfer-Encoding | HTTP_HDR_FIELD_TRANSFER_ENCODING |
Accept | HTTP_HDR_FIELD_ACCEPT |
Accept-Charset | HTTP_HDR_FIELD_ACCEPT_CHARSET |
Accept-Encoding | HTTP_HDR_FIELD_ACCEPT_ENCODING |
Accept-Language | HTTP_HDR_FIELD_ACCEPT_LANGUAGE |
Accept-Ranges | HTTP_HDR_FIELD_ACCEPT_RANGES |
Age | HTTP_HDR_FIELD_AGE |
Allow | HTTP_HDR_FIELD_ALLOW |
Authorization | HTTP_HDR_FIELD_AUTHORIZATION |
Content-Encoding | HTTP_HDR_FIELD_CONTENT_ENCODING |
Content-Language | HTTP_HDR_FIELD_CONTENT_LANGUAGE |
Content-Location | HTTP_HDR_FIELD_CONTENT_LOCATION |
Content-MD5 | HTTP_HDR_FIELD_CONTENT_MD5 |
Content-Range | HTTP_HDR_FIELD_CONTENT_RANGE |
Cookie | HTTP_HDR_FIELD_COOKIE |
Cookie2 | HTTP_HDR_FIELD_COOKIE2 |
Date | HTTP_HDR_FIELD_DATE |
ETag | HTTP_HDR_FEILD_ETAG |
Expect | HTTP_HDR_FIELD_EXPECT |
Expires | HTTP_HDR_FIELD_EXPIRES |
From | HTTP_HDR_FIELD_FROM |
If-Modified-Since | HTTP_HDR_FIELD_IF_MODIFIED_SINCE |
If-Match | HTTP_HDR_FIELD_IF_MATCH |
If-None-Match | HTTP_HDR_FIELD_IF_NONE_MATCH |
If-Range | HTTP_HDR_FIELD_IF_RANGE |
If-Unmodified-Since | HTTP_HDR_FIELD_IF_UNMODIFIED_SINCE |
Last-Modified | HTTP_HDR_FIELD_LAST_MODIFIED |
Range | HTTP_HDR_FIELD_RANGE |
Referrer | HTTP_HDR_FIELD_REFERER |
Retry-After | HTTP_HDR_FIELD_RETRY_AFTER |
Server | HTTP_HDR_FIELD_SERVER |
Set-Cookie | HTTP_HDR_FIELD_SET_COOKIE |
Set-Cookie2 | HTTP_HDR_FIELD_SET_COOKIE2 |
TE | HTTP_HDR_FIELD_TE |
Trailer | HTTP_HDR_FIELD_TRAILER |
Upgrade | HTTP_HDR_FIELD_UPGRATE |
User-Agent | HTTP_HDR_FIELD_USER_AGENT |
Vary | HTTP_HDR_FIELD_VARY |
Via | HTTP_HDR_FIELD_VIA |
Warning | HTTP_HDR_FIELD_WARNING |
WWW-Authenticate | HTTP_HDR_FIELD_WWW_AUTHENTICATE |
If a header is missing for your application, contact your sales representative so that it can be included in subsequent release of Micrium OS. |
---|
HTTP Content Types#
MIME Content Type | File Extension | Micrium Type |
---|---|---|
text/html | .html | HTTP_CONTENT_TYPE_HTML |
application/octet-stream | .bin | HTTP_CONTENT_TYPE_OCTET_STREAM |
application/pdf | HTTP_CONTENT_TYPE_PDF | |
application/zip | .zip | HTTP_CONTENT_TYPE_ZIP |
image/gif | .gif | HTTP_CONTENT_TYPE_GIF |
image/jpeg | .jpeg, .jpg | HTTP_CONTENT_TYPE_JPEG |
image/png | .png | HTTP_CONTENT_TYPE_PNG |
application/javascript | .js | HTTP_CONTENT_TYPE_JS |
text/plain | .txt | HTTP_CONTENT_TYPE_PLAIN |
text/css | .css | HTTP_CONTENT_TYPE_CSS |
application/json | .json | HTTP_CONTENT_TYPE_JSON |
application/x-www-form-urlencoded | - | HTTP_CONTENT_TYPE_APP_FORM |
multipart/form-data | - | HTTP_CONTENT_TYPE_MULTIPART_FORM |
If a Content Type is missing for your application, contact your sales representative so that it can be included in subsequent release of Micrium OS. |
---|
HTTP Status Codes#
HTTP Status Code | Micrium Type |
---|---|
200 | HTTP_STATUS_OK |
201 | HTTP_STATUS_CREATED |
202 | HTTP_STATUS_ACCEPTED |
204 | HTTP_STATUS_NO_CONTENT |
205 | HTTP_STATUS_RESET_CONTENT |
301 | HTTP_STATUS_MOVED_PERMANENTLY |
302 | HTTP_STATUS_FOUND |
303 | HTTP_STATUS_SEE_OTHER |
304 | HTTP_STATUS_NOT_MODIFIED |
305 | HTTP_STATUS_USE_PROXY |
307 | HTTP_STATUS_TEMPORARY_REDIRECT |
400 | HTTP_STATUS_BAD_REQUEST |
401 | HTTP_STATUS_UNAUTHORIZED |
403 | HTTP_STATUS_FORBIDDEN |
404 | HTTP_STATUS_NOT_FOUND |
405 | HTTP_STATUS_METHOD_NOT_ALLOWED |
406 | HTTP_STATUS_NOT_ACCEPTABLE |
408 | HTTP_STATUS_REQUEST_TIMEOUT |
409 | HTTP_STATUS_CONFLICT |
410 | HTTP_STATUS_GONE |
411 | HTTP_STATUS_LENGTH_REQUIRED |
412 | HTTP_STATUS_PRECONDITION_FAILED |
413 | HTTP_STATUS_REQUEST_ENTITY_TOO_LARGE |
414 | HTTP_STATUS_REQUEST_URI_TOO_LONG |
415 | HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE |
416 | HTTP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE |
417 | HTTP_STATUS_EXPECTATION_FAILED |
500 | HTTP_STATUS_INTERNAL_SERVER_ERR |
501 | HTTP_STATUS_NOT_IMPLEMENTED |
503 | HTTP_STATUS_SERVICE_UNAVAILABLE |
505 | HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED |
If a Status Code is missing for your application, contact your sales representative so that it can be included in subsequent release of Micrium OS. |
---|
HTTP Server Module#
The Micrium HTTP Server can be used in the more traditional way, meaning used to store web pages and web resources that can be fetched through Web Browsers. In that view, HTTP Server is compliant with all the available browsers (Firefox, Chrome, Safari, etc.) for computer systems.
HTTP Server can also be used in a more web service style, i.e., to fetch, modify and create web resources that are not necessarily files.
HTTP Server Overview#
Specifications#
Complies with the following RFC:
RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1
Implemented methods:
GET
POST
PUT
DELETE
HEAD
Features#
Scalable to contain only required features and minimize memory footprint.
Add-on modules are also given to enhance and simplify the development of your HTTP server application.
Supports file storage via Micrium OS File System or can be used via a "Static File System" which is provided inside the HTTP Server source code. The server can also be used without any File System.
Supports multiple instances, i.e., it’s possible to launch many web server on different TCP ports. This allows, for example, to have a part of a web application without security and another part with SSL/TLS security.
Supports up to 255 connections simultaneously (using only one task).
Allows application programmers to define “hook” functions, which are called by the HTTP Server stack when processing a request.
Provides many (optional) built-in statistics and error counters that can be used for debugging or for logging usage statistics.
Allows to specify a working directory for each HTTP server instance (Only when Micrium OS File System is used as a File System).
Supports secure Web Servers (HTTPs).
Supports persistent connections .
Supports HTTP REST .
Supports Dynamic Token Replacement in web pages and text files.
Supports HTTP Query String
Supports reception of HTTP headers in requests and addition of HTTP headers in responses.
Supports application and multipart forms .
Supports chunked transfer encoding in transmission.
Limitations#
No support for WebSockets yet.
HTTP Server Example Applications#
This section describes the examples that are related to the HTTP Server module of Micrium OS.
Server That Handles Web pages, REST Requests and Authentication Support
Basic Secure Server That Uses SSL-TLS and the HTTP Static File System
HTTP Server Initialization Example#
Description#
This is a generic example that shows how to initialize the HTTP Server module. It accomplishes the following tasks:
Initialize the HTTP Server module
Create a RAM disk for file exchange
Configuration#
Mandatory#
The following #define must be added in ex_description.h to allow other examples to initialize the HTTP Server module correctly:
#define | Description |
---|---|
EX_HTTP_SERVER_INIT_AVAIL | Lets the upper example layer know that the HTTP Server Initialization example is present and must be called by other examples. |
Location#
/examples/net/http/server/ex_http_server_init.c
/examples/net/http/server/ex_http_server.h
API#
API | Description |
---|---|
Ex_HTTP_Server_Init() | Initialize the HTTP Server stack for the example application. |
Notes#
None.
Simple Server That Uses No File System#
Description#
This is a simple HTTP server example that demonstrates how to create a web page server without the use of a File System (Micrium OS File System or HTTP static FS).
The web server simply displays a "Hello World!" message on the web page once it is loaded.
Configuration#
None.
Location#
/examples/net/http/server/ex_http_server_no_fs.c
/examples/net/http/server/ex_http_server_hooks.c
/examples/net/http/server/ex_http_server_hooks.h
/examples/net/http/server/ex_http_server_init.c
/examples/net/http/server/ex_http_server.h
API#
API | Description |
---|---|
Ex_HTTP_Server_InstanceCreateNoFS() | Initializes and starts a basic web server instance. |
Basic Server That Uses the HTTP Static File System#
Description#
This is a basic HTTP server example that demonstrates how to create a web page server using the HTTP server static file system.
The web server displays some web pages and a form once it is loaded.
Configuration#
None.
Location#
/examples/net/http/server/ex_http_server_basic_static_fs.c
/examples/net/http/server/ex_http_server_hooks.c
/examples/net/http/server/ex_http_server_hooks.h
/examples/net/http/server/ex_http_server_init.c
/examples/net/http/server/ex_http_server.h
The content of the folder /examples/net/http/server/files
API#
API | Description |
---|---|
Ex_HTTP_Server_InstanceCreateStaticFS() | Initializes and starts a basic web server instance. Retrieves files from the built-in static file system. |
Basic Server That Uses Micrium OS File System#
Description#
This is a basic HTTP server example that demonstrates how to create a web page server. The functionalities are similar to the "Basic Server that Uses the HTTP static File System" example. However, the web pages are retrieved using Micrium OS File System.
The web server displays some web pages and a form once it is loaded.
Configuration#
None.
Location#
/examples/net/http/server/ex_http_server_basic_fs.c
/examples/net/http/server/ex_http_server_hooks.c
/examples/net/http/server/ex_http_server_hooks.h
/examples/net/http/server/ex_http_server_init.c
/examples/net/http/server/ex_http_server.h
The content of the folder /examples/net/http/server/files
API#
API | Description |
---|---|
Ex_HTTP_Server_InstanceCreateBasic() | Initializes and starts a basic web server instance. Retrieves files from the Micrium OS file system. |
Server That Handles REST Requests#
Description#
This is a simple HTTP server example that demonstrates how to handle REST requests. It uses the HTTP static file system to store the web pages.
The web server displays some web pages and a form once it is loaded. It also offers a form that allows adding entries to a database via REST requests.
Configuration#
None.
Location#
/examples/net/http/server/ex_http_server_rest.c
/examples/net/http/server/ex_http_server_rest_hooks.c
/examples/net/http/server/ex_http_server_rest_hooks.h
/examples/net/http/server/ex_http_server_init.c
/examples/net/http/server/ex_http_server.h
The content of the folder /examples/net/http/server/files
API#
API | Description |
---|---|
Ex_HTTP_Server_InstanceCreateREST() | Initialize HTTPs REST Example application. |
Server That Handles Webpages, REST Requests and Authentication Support#
Description#
This is an HTTP server example that demonstrates how to handle web pages, RESTrequestsand authentication in a single instance. It requires the use of the Control Layer. It uses the HTTP static file system to store the web pages.
The web server displays some web pages and a form once it is loaded. It also offers a form that allows adding entries to a database via REST requests.
Note that you will have to login first before accessing the pages. The example will create the following user accounts:
Username | admin | user0 | user1 |
---|---|---|---|
Password | password | <empty> | user1 |
Rights | Manager of HTTP user access right | HTTP user | HTTP user |
Configuration#
None.
Location#
/examples/net/http/server/ex_http_server_ctrl_layer.c
/examples/net/http/server/ex_http_server_hooks.c
/examples/net/http/server/ex_http_server_hooks.h
/examples/net/http/server/ex_http_server_rest_hooks.c
/examples/net/http/server/ex_http_server_rest_hooks.h
/examples/net/http/server/ex_http_server_init.c
/examples/net/http/server/ex_http_server.h
The content of the folder /examples/net/http/server/files
API#
API | Description |
---|---|
Ex_HTTP_Server_InstanceCreateCtrlLayer() | Initialize HTTPs REST Example application. |
Basic Secure Server That Uses SSL-TLS and the HTTP Static File System#
Description#
This is a basic HTTP server example that demonstrates how to create asecurewebserverusingSSL-TLS and the HTTP server static file system.
The web server displays some web pages and a form once it is loaded.
Configuration#
None.
Location#
/examples/net/http/server/ex_http_server_ssl_tls_static_fs.c
/examples/net/http/server/ex_http_server_hooks.c
/examples/net/http/server/ex_http_server_hooks.h
/examples/net/http/server/ex_http_server_init.c
/examples/net/http/server/ex_http_server.h
The content of the folder /examples/net/http/server/files
API#
API | Description |
---|---|
Ex_HTTP_Server_InstanceCreateSecure() | Initialize HTTPs REST Example application. |
Notes#
None
HTTP Server Configuration#
In order to address your application's needs, the HTTP Server module must be properly configured. There are three groups of configuration parameters:
HTTP Server Compile-time Configuration#
The HTTP Server module is configurable at compile time via several #defines located in http_server_cfg.h file. It uses #defines when possible, because they allow code and data sizes to be scaled at compile time based on enabled features. This allows the Read-Only Memory (ROM) and Random-Access Memory (RAM) footprints of the HTTP Server to be adjusted based on application requirements.
It is recommended that the configuration process begins with the default configuration values which in the next sections will be shown in bold.
Debug Configuration#
A fair amount of code in the HTTP Server module has been included to simplify debugging. There are several configuration constants used to aid debugging.
Table - Argument Checking and Debug Configuration#
Constant | Description | Possible Values |
---|---|---|
HTTPs_CFG_DBG_INFO_EN | Enable/disable HTTP Server debug information: Internal constants assigned to global variables. | DEF_ENABLED or DEF_DISABLED |
Counter Configuration#
The HTTP Server contains code that increments counters to keep track of statistics such as the number of request received, the number of connection processed, etc. Also, the HTTP Server module contains counters that are incremented when error conditions are detected. The following constants enable or disable HTTP counters.
Table - Counter Configuration#
Constant | Description | Possible Values |
---|---|---|
HTTPs_CFG_CTR_STAT_EN | Determines whether the code and data space used to keep track of statistics will be included. | DEF_ENABLED or DEF_DISABLED |
HTTPs_CFG_CTR_ERR_EN | Determines whether the code and data space used to keep track of errors will be included. | DEF_ENABLED or DEF_DISABLED |
File System Configuration#
The HTTP Server can be used with a standard file system like Micrium OS File System.
Table - File System Configuration#
Constant | Description | Possible Values |
---|---|---|
HTTPs_CFG_FS_PRESENT_EN | Determines whether or not a File System is present and must be used with HTTP server. | DEF_DISABLED or DEF_ENABLED |
Persistent Connection Configuration#
The HTTP Server supports persistent connection when HTTP protocol version 1.1 is used.
The configuration related to Persistent Connection must also be enabled in the run-time configuration of each server instance for which this feature is desired. See section Instance Configuration for more details.
See section Persistent Connection for more details on HTTP Persistent Connection.
Table - Persistent Connection Configuration#
Constant | Description | Possible Values |
---|---|---|
HTTPs_CFG_PERSISTENT_CONN_EN | Determines whether the code and data used to support the persistent connection feature will be included. | DEF_DISABLED or DEF_ENABLED |
Header Field Configuration#
The HTTP Server contains code that allow the upper application to receive header field received in the request message and add header field to be transmitted with the response message.
The header parameters must also be defined in the run-time configuration of each server instance for which this feature is wished. See section Instance Configuration and HTTP Header Configuration for more details.
See section Headers for more details on HTTP header fields concept.
Table - Header Field Configuration#
Constant | Description | Possible Values |
---|---|---|
HTTPs_CFG_HDR_RX_EN | Determines whether the code and data space used to support additional header field in request will be included. | DEF_ENABLED or DEF_DISABLED |
HTTPs_CFG_HDR_TX_EN | Determines whether the code and data space used to support additional header field in response will be included. | DEF_ENABLED or DEF_DISABLED |
Query String Configuration#
The HTTP Server contains code to allow the parsing and saving of Query String received in HTTP requests.
To enable this feature for a specific server instance, the parameter associated with the Query String must also be enabled in the the run-time configuration of the instance. See section Instance Configuration and Query String Configuration for more details on the configuration.
See section Query String for additional details on the HTTP Query String concept.
Table - Query String Configuration#
Constant | Description | Possibles Values |
---|---|---|
HTTPs_CFG_QUERY_STR_EN | Determines whether the code and data space used to support Query String in HTTP request will be included. | DEF_ENABLED or DEF_DISABLED |
Form Submission Configuration#
The HTTP Server can support the reception of HTML forms using the HTTP POST method. The HTTP Server module is designed to manage different type of form encoding and also to upload files from an HTML form.
To enable this feature for a specific server instance, the parameter associated with the Form feature must also be enabled in the the run-time configuration of the instance. See section Instance Configuration and HTTP Form Configuration for more details on the configuration.
See section Form for additional details on the HTML Form concept.
Table - Dynamic Content Configuration#
Constant | Description | Possible Values |
---|---|---|
HTTPs_CFG_FORM_EN | Determines whether the code and data space used to support forms submission will be included. If the server does not host form, this feature should be disabled in order to speed up processing. If this feature is set as disabled all other Form's configurations are automatically disabled. | DEF_ENABLED or DEF_DISABLED |
HTTPs_CFG_FORM_MULTIPART_EN | Determines whether the code and data space used to support forms submission with “multipart/form-data” encoding will be included. | DEF_ENABLED or DEF_DISABLED |
Token Replacement Configuration#
A considerable amount of code in the HTTP Server has been included to parse, replace and transmit HTML document with dynamic content using token replacement and the HTTP Chunked Transfer encoding.
To enable this feature for a specific server instance, the parameter associated with the Token feature must also be enabled in the the run-time configuration of the instance. See section Instance Configuration and Token Configuration for more details on the configuration.
Table - Dynamic Content Configuration#
Constant | Description | Possible Values |
---|---|---|
HTTPs_CFG_TOKEN_PARSE_EN | Determines whether the code and data space used to support the parsing of the tokens found in HTML files for dynamic content will be included. If the server does not host dynamic content, the feature should be disabled in order to speed up processing. | DEF_DISABLED or DEF_ENABLED |
Proxy Configuration#
The HTTP Server module can be accessed even if it is located behind a proxy.
Table - Proxy Configuration#
Constant | Description | Possible Values |
---|---|---|
HTTPs_CFG_ABSOLUTE_URI_EN | Determines whether the code and data space used to support header field for absolute URI. | DEF_ENABLED or DEF_DISABLED |
HTTP Server Compile-Time Configuration for Static File System#
HTTP Server's static file system is configurable at compile time via three #defines located in http_server_fs_port_static_cfg.h file. The HTTP Server module uses #defines when possible, because they allow code and data sizes to be scaled at compile time based on enabled features. This allows the Read-Only Memory (ROM) and Random-Access Memory (RAM) footprints of the HTTP Server to be adjusted based on application requirements.
It is recommended that the configuration process begins with the default configuration values which in the next sections will be shown in bold.
These configurations are necessary only if you use the static file system in your application. |
---|
Constant | Description | Possible Values |
---|---|---|
HTTPs_FS_CFG_NBR_FILES | This value defines the maximum number of files the static file system could manage. | 1 or more. Default is 15. |
HTTPs_FS_CFG_NBR_DIRS | This value defines the maximum number of directories the static file system could manage. | 1 or more. Default is 1. |
HTTPs_FS_CFG_MAX_FILE_NAME_LEN | This value defines the maximum file name length. | 1 or more. Default is 256. |
HTTP Server Run-Time Application Specific Configuration#
This section defines the configurations related to the HTTP Server module but that are specified at run-time, during the initialization process.
Initialization#
Initializing the HTTP Server module is done by calling the function HTTPs_Init(). This function takes no configuration argument. Unless you override an optional configuration before calling the function HTTPs_Init(), the default configurations will be used.
Optional Configurations#
This section describes the configurations that are optional. If you do not set them in your application, the default configurations will apply.
The default values can be retrieved via the structure HTTPs_InitCfgDflt.
Note that these configurations must be set before you call the function HTTPs_Init(). |
---|
Table - HTTP Server Optional Configurations#
Configurations | Description | Type | Function to call | Default | Field from default configuration structure |
---|---|---|---|---|---|
Memory segment | This module allocates some control data. You can specify the memory segment from where such data should be allocated. | MEM_SEG* | HTTPs_ConfigureMemSeg() | .MemSegPtr |
Post-Init Configurations#
This section describes the configurations that can be set at any time during execution AFTER you called the function HTTPs_Init().
These configurations are optional. If you do not set them in your application, the default configurations will apply.
Table - HTTP Server Post-init Configurations#
Configurations | Description | Type | Function to call | Default |
---|---|---|---|---|
HTTP server instance task priority | Each HTTP server instance created via the function HTTPs_InstanceInit() will create a task. You can change the priority of the created task at any time.. | RTOS_TASK_PRIO | HTTPs_InstanceTaskPrioSet() | N/A |
HTTP Server Instance Configuration#
This section defines the configurations related to the HTTP Server module that are specified at run-time and that are specific to each added HTTP server instance.
To add a HTTP server instance, call the HTTPs_InstanceInit() function. This function requires two configurations arguments (described below).
p_cfg#
p_cfg
is a pointer to a configuration structure of type HTTPs_CFG. The HTTP Server instance configuration is based on a large structure that contains different configuration sections with many parameter settings. This section should provide you an in-depth understanding of all instance parameter configuration. You will also discover which settings to modify in order to enhance the functionalities and the performances. Refer to the configuration field description section for further details. The HTTPs_CFG object must be passed to the HTTPs_InstanceInit() API function during the initialization of the HTTP server instance.
Task#
Table - Task Configuration#
Structure Field | Type | Description | Possible Values |
---|---|---|---|
.OS_TaskDly_ms | CPU_INT32U | Configure instance task delay in integer millisecondsThe web server can delay his task periodically to allow another task with lower priority to run. | MUST be >= 0 |
Listen Socket#
Table - Listen Socket Configuration#
Structure Field | Type | Description | Possible Values | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
.SockSel | HTTPs_SOCK_SEL | Configure socket type. Select which kind of IP addresses can be accepted by the web server instance.When only one IP type is selected, only one socket and TCP connection will be reserved to listen for incoming connections.When the two IP types are selected, two sockets and TCP connections will be reserved for listening. | - HTTPs_SOCK_SEL_IPv4 (Accept Only IPv4)- HTTPs_SOCK_SEL_IPv6 (Accept Only IPv6)- HTTPs_SOCK_SEL_IPv4_IPv6 (Accept IPv4 and IPv6) | ||||||||||||||||||||
.SecurePtr | HTTPs_SECURE_CFG | Configure instance secure (SSL/TLS) configuration structure.'Secure' field is used to enabled or disable SSL/TLS:1. DEF_NULL, the web server instance is not secure and doesn't use SSL/TLS.2. Point to a secure configuration structure, the web server is secure and use SSL/TLS.The secure web server can be enabled only if the application project contains a secure module supported by the Network module such as:1. NanoSSL provided by Mocana.2. CyaSSL provided by YaSSL. | - DEF_NULL for a non-secure web server- Pointer to the secure configuration (Instance^Secure^Configuration ) to be used. | ||||||||||||||||||||
.Port | CPU_INT16U | Configure instance server port.1. Default HTTP port used by all web browser is 80. The default port number is defined by the following value:HTTPs_CFG_DFLT_PORTWhen default port is used the web server instance can be accessed using the IP address of the target from any web browser:http://*\\ | <target ip address\ | >If the web server instance is configured with the non-default port, the instance server should be accessed via this kind of address:http://\ | <target ip address\ | >:\ | <port number\ | >Where: \ | <target ip address\ | > must be replaced by the IP address of the target. \ | <port number\ | > must be replaced by the configured port number.2. Default secure port used by all browser is 443. The default secure port number is defined by the following value:HTTPs_CFG_FDLT_PORT_SECUREWhen default port is used the web server instance can be accessed using the IP address of the target from any web browser:https:// \ | <target ip address\ | >If the web server instance is configured with the non-default port, the instance server should be accessed via this kind of address:https:// \ | <target ip address\ | > : \ | <port number\ | >Where\ | <target ip address\ | > must be replaced by the IP address of the target.\ | <port number\ | >* must be replaced by the configured port number.3. Port number must be unique, i.e., it's not possible to start two instances with the same port number. | - HTTPs_CFG_DFLT_PORT (Default HTTP port)- HTTPs_CFG_FDLT_PORT_SECURE Default (HTTP SSL port) |
Connection#
Table - Connection Configuration#
Structure Field | Type | Description | Possible Values |
---|---|---|---|
.ConnNbrMax | CPU_INT08U | Configure the maximum number of simultaneous connections.'ConnNbrMax' is used to configure the maximum number of connections that the web server will be able to serve simultaneously.The maximum number of connections must be configured following your requirements about the memory usage and the number of connection:- Each connection requires memory space. So the memory required by the web server is greatly affected by the number of connection configured.- When a client downloads an item such as HTML document, image, CSS file, Javascript file, it should open a new connection for each of these items when the Persistent Connection feature is disabled. Also, most common web server can open up to 15 simultaneous connections. As an example, for an HTML document which includes 2 images + 1 CSS file, 4 connections could be opened simultaneously.The number of connection and the Network core module configuration must be configured accordingly. Each connection requires 1 TCP socket and the server requires 1 or 2 TCP socket depending if IPv4 and IPv6 connection can be accepted, see TCP Layer Configuration and Socket Layer Configuration to properly configure the web instance and Micrium OS Network module. | MUST be >= 1 |
.ConnInactivityTimeout_s | CPU_INT16U | Configure connection maximum inactivity timeout in integer seconds.For each connection when the inactivity timeout occurs the connection is automatically closed whatever what the state of the connection was. | SHOULD be >= 1 |
.BufLen | CPU_INT16U | Configure connection buffer length.Each connection has a buffer to receive & transmit data and to read file. If the memory is limited the buffer size can be reduced, but the performance could be impacted. | MUST be >= 512 |
.ConnPersistentEn | CPU_BOOLEAN | Configure Persistent Connection feature.See section Persistent Connection for more details on the Persistent Connection concept. | - DEF_DISABLED- DEF_ENABLED |
File System#
See section File System Configuration for additional details on the File System configuration and configuration structures.
Table - File System Configuration#
Structure Field | Type | Description | Possible Values |
---|---|---|---|
.FS_Type | HTTPs_FS_TYPE | Configure the Type of File System to use with the HTTP server:HTTPs_FS_TYPE_NONE : No File System is present.HTTPs_FS_TYPE_STATIC : Use the HTTP Static File System offered inside the HTTP-server.HTTPs_FS_TYPE_DYN : Use a standard dynamic File System (e.g., Micrium OS File System) | HTTPs_FS_TYPE_NONEHTTPs_FS_TYPE_STATICHTTPs_FS_TYPE_DYN |
.FS_CfgPtr | const void* | Configure Pointer to the File System Configuration object.Each File System Type has its configuration structure:HTTPs_CFG_FS_NONEHTTPs_CFG_FS_STATICHTTPs_CFG_FS_DYN | MUST be a valid pointer. |
.DfltResourceNamePtr | CPU_CHAR* | Configure instance default HTML document.The default HTML document is returned when no file is specified in the request of the client, i.e., accessing with only the web server address. Most of the time this file should be "index.html". | MUST be a string pointer |
Proxy#
Table - Proxy Configuration#
Structure Field | Type | Description | Possible Values |
---|---|---|---|
.HostNameLenMax | CPU_INT16U | Configure maximum host name length.When an HTTP Server is behind an HTTP Proxy, the HTTP client must send its requests with an absolute URI. For example :GET http://example.com/index.html HTTP/1.1When the absolute URI feature is enabled, the HTTP server will support absolute URI in the first line of the HTTP request messages (see the example just above). The server will also look for the 'Host' header field in the received request messages and save it in the HostPtr field of the HTTPs_CONN structure.The maximum host name length is the maximum length the server will allow for the received host name in a request message.Proxy support must be enabled to allow the web server to support absolute URI. See Proxy Configuration for further information. | SHOULD be >= 1. |
Hook Functions#
See Section Hook Configuration for additional details on the hook functions configuration structure.
Table - Hook Functions Configuration#
Structure Field | Type | Description | Possible Values |
---|---|---|---|
.HookPtr | const HTTPs_HOOK_CFG Pointer | Pointer to an HTTPs_HOOK_CFG type object. This object contains all the hook function pointers available to personalize the processing of HTTP requests received. | Pointer to Hook object or DEF_NULL. |
.Hook_CfgPtr | void* | Data associated with the Hook set-up that will be available inside each hook function. | Pointer to Hook Configuration object or DEF_NULL. |
Header Field#
See Section HTTP Header Configuration for additional details on the Header Configuration structures.
Table - Header Field Configuration#
Structure Field | Type | Description | Possible Values |
---|---|---|---|
.HdrRxCfgPtr | const HTTPs_HDR_RX_CFG Pointer | Configure pointer to HTTP Request (RX) Header Configuration object structure. | Pointer to Configuration object structure.DEF_NULL, if feature not necessary. |
.HdrTxCfgPtr | const HTTPs_HDR_TX_CFG Pointer | Configure pointer to HTTP Response (TX) Header Configuration object structure. | Pointer to Configuration object structure.DEF_NULL, if feature not necessary. |
Query String#
See section Query String Configuration for additional details on Query String Configuration structure.
Table - Query String Configuration#
Structure Field | Type | Description | Possible Values |
---|---|---|---|
.QueryStrCfgPtr | const HTTPs_QUERY_STR_CFG Pointer | Configure pointer to HTTP Query String Configuration object structure. | Pointer to Configuration object structure.DEF_NULL, if feature not necessary. |
Form#
See section HTTP Form Configuration for additional details on Form Configuration structure.
Table - Form Configuration#
Structure Field | Type | Description | Possible Values |
---|---|---|---|
.FormCfgPtr | const HTTPs_FORM_CFG Pointer | Configure pointer to HTML Form Configuration object structure. | Pointer to Configuration object structure.DEF_NULL, if feature not necessary. |
Dynamic Token Replacement#
See section Token Configuration for additional details on Token Configuration structure.
Table - Token Configuration#
Structure Field | Type | Description | Possible Values |
---|---|---|---|
.Token_CfgPtr | const HTTPs_TOKEN_CFG Pointer | Configure pointer to Token Replacement Configuration object structure. | Pointer to Configuration object structure.DEF_NULL, if feature not necessary. |
p_task_cfg#
Each HTTP server instance has a kernel task associated. p_task_cfg is a pointer to a configuration structure of type RTOS_TASK_CFG that allows you to configure the priority, stack base pointer, and stack size for that task.
Guidelines on How to Properly Set the Priority and Stack Size#
The priority of an HTTP Server instance's task greatly depends on the requirements of your application. For some applications, it might be better to set it at a high priority, especially if your application requires a lot of tasks and is CPU intensive.
Task Stack Sizes#
The arbitrary stack size of 1024 is a good starting point for most applications.
The only guaranteed method of determining the required task stack sizes is to calculate the maximum stack usage for each task. Obviously, the maximum stack usage for a task is the total stack usage along the task’s most-stack-greedy function path. Note that the most-stack-greedy function path is not necessarily the longest or deepest function path.
The easiest and best method for calculating the maximum stack usage for any task/function should be performed statically by the compiler or by a static analysis tool since these can calculate function/task maximum stack usage based on the compiler’s actual code generation and optimization settings. So for optimal task stack configuration, we recommend that you invest in a task stack calculator tool compatible with your build toolchain.
HTTP Server Instance Secure Configuration#
The HTTPs_SECURE_CFG structure referenced in instance configuration must exist throughout the lifetime of the HTTPs instance since the certificate and the key are not copied internally and are directly referenced throughout the HTTPs_SECURE_CFG pointer.
SSL/TLS certificate and key can be acquired either:
From a certificate authority. Acquiring the certificate from an authority should ensure to avoid the untrusted warning message to be displayed when accessing the web server.
Generated from a SSL tool such as OpenSSL. This kind of tool generates self-signed certificate and the untrusted warning message will be displayed every time the web server is accessed.
Configuration Field Description#
Table - Secure Configuration#
Structure Field | Type | Description | Possible Values |
---|---|---|---|
.CertPtr | CPU_CHAR * | Pointer to the public certificate’s character string. | String |
.CertLen | CPU_INT32U | Length of the public certificate. | MUST BE > 0 |
.KeyPtr | CPU_CHAR * | Pointer to the private key’s character string. | String |
.KeyLen | CPU_INT32U | Length of the private key. | MUST BE > 0 |
.Fmt | NET_SOCK_SECURE_CERT_KEY_FMT | Format of the key and certificate. Supported formats are PEM and DER.If the PEM format is used, do not include the “-----BEGIN CERTIFICATE-----”, “-----END CERTIFICATE-----”, “-----BEGIN RSA PRIVATE KEY-----” or “-----END RSA PRIVATE KEY-----” sections. | - NET_SOCK_SECURE_CERT_KEY_FMT_PEM- NET_SOCK_SECURE_CERT_KEY_FMT_DER |
.CertChain | CPU_BOOLEAN | Flag to set if the certificate is chained to another one. | - DEF_NO- DEF_YES |
Structure Example#
Listing - Secure Configuration Structure Example in the HTTP Server Instance Secure Configuration page demonstrates how to create an HTTP Server secure configuration structure.
Listing - Secure Configuration Structure Example#
#define HTTPs_CFG_SECURE_CERT \
"MIIEEjCCAvqgAwIBAgIBBzANBgkqhkiG9w0BAQUFADAaMRgwFgYDVQQDEw9WYWxp\
Y29yZS1EQzEtQ0EwHhcNMTEwMzE4MTcwMTQyWhcNMjEwMzE1MTcwMTQyWjCBkDEL\
MAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQ8wDQYDVQQHEwZJcnZpbmUxHjAcBgNV\
BAoTFVZhbGljb3JlIFRlY2hub2xvZ2llczEhMB8GA1UEAxMYbGFuLWZ3LTAxLnZh\
bGljb3JlLmxvY2FsMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBsb2NhbGRvbWFpbjCC\
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALwGOahytiwshzz1s/ngxy1+\
+VrXZYjKSEzMYbJCUhK9xA5fz8pGtOZIXI+CasZPSbXv+ZDLGpSpeFnOL49plYRs\
vmTxg2n3AlZbP6pD9OPU8rmufsTvXAmQGxxIkdmWiXYJk0pbj+U698me6DKMV/sy\
3ekQaQC2I2nr8uQw8RhuNhhlkWyjBWdXnS2mLNLSan2Jnt8rumtAi3B+vF5Vf0Fa\
kLJNt45R0f5jjuab+qw4PKMZEQbqe0XTNzkxdD0XNRBdKlajffoZPBJ7xkfuKUA3\
cMjXKzetABoKvsv+ElfvqlrI9RXvTXy52EaQmVhiOyBHrScq4RbwtDQsd59Qmk0C\
AwEAAaOB6zCB6DAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIGQDA0BglghkgB\
hvhCAQ0EJxYlRWFzeS1SU0EgR2VuZXJhdGVkIFNlcnZlciBDZXJ0aWZpY2F0ZTAd\
BgNVHQ4EFgQUrq5KF11M9rpKm75nAs+MaiK0niYwUQYDVR0jBEowSIAU2Q9eGjzS\
LZhvlRRKO6c4Q5ATtuChHqQcMBoxGDAWBgNVBAMTD1ZhbGljb3JlLURDMS1DQYIQ\
T9aBcT0uXoxJmC0ohp7oSTATBgNVHSUEDDAKBggrBgEFBQcDATALBgNVHQ8EBAMC\
BaAwDQYJKoZIhvcNAQEFBQADggEBAAUMm/9G+mhxVIYK4anc34FMqu88NQy8lrh0\
loNfHhIEKnerzMz+nQGidf+KBg5K5U2Jo8e9gVnrzz1gh2RtUFvDjgosGIrgYZMN\
yreNUD2I7sWtuWFQyEuewbs8h2MECs2xVktkqp5KPmJGCYGhXbi+zuqi/19cIsly\
yS01kmexwcFMXyX4YOVbG+JFHy1b4zFvWgSDULj14AuKfc8RiZNvMRMWR/Jqlpr5\
xWQRSmkjuzQMFavs7soZ+kHp9vnFtY2D6gF2cailk0sdG0uuyPBVxEJ2meifG6eb\
o3FQzdtIrB6oMFHEU00P38SJq+mrDItPDRXNLa2Nrtc1EJtmjws="
#define HTTPs_CFG_SECURE_KEY \
"MIIEogIBAAKCAQEAvAY5qHK2LCyHPPWz+eDHLX75WtdliMpITMxhskJSEr3EDl/P\
yka05khcj4Jqxk9Jte/5kMsalKl4Wc4vj2mVhGy+ZPGDafcCVls/qkP049Tyua5+\
xO9cCZAbHEiR2ZaJdgmTSluP5Tr3yZ7oMoxX+zLd6RBpALYjaevy5DDxGG42GGWR\
bKMFZ1edLaYs0tJqfYme3yu6a0CLcH68XlV/QVqQsk23jlHR/mOO5pv6rDg8oxkR\
Bup7RdM3OTF0PRc1EF0qVqN9+hk8EnvGR+4pQDdwyNcrN60AGgq+y/4SV++qWsj1\
Fe9NfLnYRpCZWGI7IEetJyrhFvC0NCx3n1CaTQIDAQABAoIBAEbbqbr7j//RwB2P\
EwZmWWmh4mMDrbYBVYHrvB2rtLZvYYVxQiOexenK92b15TtbAhJYn5qbkCbaPwrJ\
E09eoQRI3u+3vKigd/cHaFTIS2/Y/qhPRGL/OZY5Ap6EEsMHYkJjlWh+XRosQNlw\
01zJWxbFsq90ib3E5k+ypdStRQ7JQ9ntvDAP6MDp3DF2RYf22Tpr9t3Oi2mUirOl\
piOEB55wydSyIhSHusbms3sp2uvQBYJjZP7eENEQz55PebTzl9UF2dgJ0wJFS073\
rvp46fibcch1L7U6v8iUNaS47GTs3MMyO4zda73ufhYwZLU5gL8oEDY3tf/J8zuC\
mNurr0ECgYEA8i1GgstYBFSCH4bhd2mLu39UVsIvHaD38mpJE6avCNOUq3Cyz9qr\
NzewG7RyqR43HsrVqUSQKzlAGWqG7sf+jkiam3v6VW0y05yqDjs+SVW+ZN5CKyn3\
sMZV0ei4MLrfxWneQaKy/EUTJMlz3rLSDM/hpJoA/gOo9BIFRf2HPkkCgYEAxsGq\
LYU+ZEKXKehVesh8rIic4QXwzeDmpMF2wTq6GnFq2D4vWPyVGDWdORcIO2BojDWV\
EZ8e7F2SghbmeTjXGADldYXQiQyt4Wtm+oJ6d+/juKSrQ1HIPzn1qgXDNLPfjd9o\
9lX5lGlRn49Jrx/kKQAPTcnCa1IirIcsmcdiy+UCgYBEbOBwUi3zQ0Fk0QJhb/Po\
LSjSPpl7YKDN4JP3NnBcKRPngLc1HU6lElny6gA/ombmj17hLZsia1GeHMg1LVLS\
NtdgOR5ZBrqGqcwuqzSFGfHqpBXEBl6SludmoL9yHUreh3QhzWuO9aFcEoNnl9Tb\
g9z4Wf8Pxk71byYISYLt6QKBgERActjo3ZD+UPyCHQBp4m45B246ZQO9zFYdXVNj\
gE7eTatuR0IOkoBawN++6gPByoUDTWpcsvjF9S6ZAJH2E97ZR/KAfijh4r/66sTx\
k26mQRPB8FHQvqv/kj3NdsgdUJJeeqPEyEzPkcjyIoJxuB7gN2El/I5wCRon3Qf9\
sQ6FAoGAfVOaROSAtq/bq9JIL60kkhA9sr3KmX52PnOR2hW0caWi96j+2jlmPT93\
4A2LIVUo6hCsHLSCFoWWiyX9pIqyYTn5L1EmeBO0+E8BH9F/te9+ZZ53U+quwc/X\
AZ6Pseyhj7S9wkI5hZ9SO1gcK4rWrAK/UFOIzzlACr5INr723vw="
#define HTTPs_CFG_SECURE_CERT_LEN (sizeof(HTTPs_CFG_SECURE_CERT) - 1)
#define HTTPs_CFG_SECURE_KEY_LEN (sizeof(HTTPs_CFG_SECURE_KEY) - 1)
HTTPs_SECURE_CFG HTTPs_Cfg_InstanceSecure = {
HTTPs_CFG_SECURE_CERT,
HTTPs_CFG_SECURE_CERT_LEN,
HTTPs_CFG_SECURE_KEY,
HTTPs_CFG_SECURE_KEY_LEN,
NET_SOCK_SECURE_CERT_KEY_FMT_PEM,
DEF_NO,
};
HTTP Server Instance File System Configuration#
The HTTP Server module can run with or without Micrium OS File System module.
If you don't use Micrium's File System and still need to store files on your HTTP server, the HTTP Server module comes with a "Static File System". This pseudo File System allows to store your files in constant C arrays, read them and navigate inside them. A script allows you to convert your files to constant C arrays that should then be added to your project. Afterwards, the function HTTPs_FS_AddFile()
allows you to store those files in the "Static File System".
Configuration#
Three types of File System can be configured with the HTTP Server. Each type has its own File System configuration structure.
In the HTTP server Instance configuration, the FS Type and the Pointer to the associated FS configuration must be passed. See section Instance Configuration .
HTTPs_FS_TYPE | Configuration Structure | Description |
---|---|---|
HTTPs_FS_TYPE_NONE | None | Use when no File System is present. |
HTTPs_FS_TYPE_STATIC | HTTPs_CFG_FS_STATIC | Use when the HTTP Server Static File System is used. |
HTTPS_FS_TYPE_DYN | HTTPs_CFG_FS_DYN | Use when Micrium OS File System module is used. |
No File System Configuration#
No configuration is required when no File System is present.
HTTP Server Static File System Configuration#
The configurations structure is of type HTTPs_CFG_FS_STATIC. Table - HTTPs_CFG_FS_STATIC Configuration Structure Description in the HTTP Server Instance File System Configuration page describes this configuration structure.
Table - HTTPs_CFG_FS_STATIC Configuration Structure Description#
Field | Type | Description | Possible Values |
---|---|---|---|
.FS_API_Ptr | const NET_FS_API* | Configure the pointer to the File System Network API object structure. | HTTPs_FS_API_Static located in http_server_fs_port_static.h. |
Dynamic File System Configuration#
The configurations structure is of type HTTPs_CFG_FS_DYN. Table - HTTPs_CFG_FS_DYN Configuration Structure Description in the HTTP Server Instance File System Configuration page describes this configuration structure.
Table - HTTPs_CFG_FS_DYN Configuration Structure Description#
Field | Type | Description | Possible Values |
---|---|---|---|
.FS_API_Ptr | const NET_FS_API* | Configure the pointer to the File System Network API object structure. | NetFS_API_Native located in net_fs.h. |
.WorkingFolderPtr | CPU_CHAR* | Pointer to the Working Folder name.Web server instances can use a working folder where files and subfolders are located. It can be set as a null pointer (DEF_NULL) if the file system doesn't support 'set working folder' functionality, but HTML documents and files must be located in the default path used by the file system. | SHOULD be a string pointer. |
HTTP Server Instance Hook Configuration#
The HTTP Server module offers multiple hook functions during the processing of an HTTP transaction.Those hooks allow the HTTP server to be customized according to your application requirements. The hook configuration is part of the HTTP server Instance configuration and must be included in the HTTPs_CFG object (see section Instance Configuration ).
See section the Hook Functions to see at what point of the process each hook is called by the server stack.
The configuration structure is of type HTTPs_HOOK_CFG. It contains only function pointers. The sections below describe this configuration structure.
.OnInstanceInitHook#
When the instance is created, a hook function can be called to initialize connection objects used by the instance (see Hook Functions page to see when this function is called).
If the hook is not required by the upper application, it can be set as DEF_NULL and no function will be called.
See Connection Objects Initialization for further details.
CPU_BOOLEAN App_OnInstanceInit (const HTTPs_INSTANCE *p_instance,
const void *p_hook_cfg);
.OnReqHdrRxHook#
Configure request header field receive callback function.
Each time a header field other than the default one is received, a hook function is called allowing to choose which header field(s) to keep for further processing.
If the hook is not required by the upper application, it can be set as DEF_NULL and no function will be called.
See Receive Request Header Field for further details.
CPU_BOOLEAN App_OnReqHdrRx (const HTTPs_INSTANCE *p_instance,
const HTTPs_CONN *p_conn,
const void *p_hook_cfg,
HTTP_HDR_FIELD hdr_field);
.OnReqHook#
Configure request hook function.
For each new incoming request, a hook function can be called by the HTTP server to authenticate the request and accept or reject it. At this point, the Start Line and the HTTP headers of the request have been parsed. The data received can be access in the HTTPs_CONN object. This function has also the right to modify some of the parameters of the HTTP transaction inside the HTTPs_CONN object.
If the hook is not required by the upper application, it can be set as DEF_NULL and no function will be called.
See Connection Request for further details.
CPU_BOOLEAN App_OnReq (const HTTPs_INSTANCE *p_instance,
HTTPs_CONN *p_conn,
const void *p_hook_cfg);
.OnReqBodyRxHook#
Configure request body data received hook function.
For some applications, it is required to parse itself the data as soon as received and not let the HTTP server core do it. It that case, this hook function allows the application to retrieve the received data directly.
If the hook is not required by the upper application, it can be set as DEF_NULL and no function will be called.
See On Request Body Received Hook for further details.
CPU_BOOLEAN App_OnReqBodyRx (const HTTPs_INSTANCE *p_instance,
HTTPs_CONN *p_conn,
const void *p_hook_cfg,
void *p_buf,
const CPU_SIZE_T buf_size,
CPU_SIZE_T *p_buf_size_used);
.OnReqRdySignalHook#
Configure request ready signal hook function.
The Signal hook function occurs after the request has been parsed completely (header + body). In the case of a POST request containing a form, all the data have been saved in the CGI key-value pairs block. The list of CGI data is available in the HTTPs_CONN object. The callback function should not be blocking and should return quickly. A time-consuming function will block the processing of the other connections and reduce the HTTP server performance.
In case the CGI data processing is time-consuming, the Poll hook function should be enabled to allow the server to periodically verify if the upper application has finished the CGI data processing.
If the CGI form feature is not enabled, this field is not used and can be set as DEF_NULL
.
See Request Ready Signal Hook for further details.
CPU_BOOLEAN App_OnReqRdySignal (const HTTPs_INSTANCE *p_instance,
HTTPs_CONN *p_conn,
const void *p_hook_cfg,
const HTTPs_KEY_VAL *p_data);
.OnReqRdyPollHook#
Configure request ready poll hook function.
The Poll hook function should be enabled in case the request data processing require lots of time. It allows the HTTP server to periodically poll the upper application and verify if the request data processing has finished.
If the Poll feature is not required, this field should be set as DEF_NULL.
See Request Ready Poll Hook for further details.
CPU_BOOLEAN App_OnReqRdyPoll (const HTTPs_INSTANCE *p_instance,
HTTPs_CONN *p_conn,
const void *p_hook_cfg);
.OnRespHdrTxHook#
Configure response header field transmit hook function.
Before an HTTP response message is sent, a hook function is called allowing to add header field(s) to the message before it is sent.
If the hook is not required by the upper application, it can be set as DEF_NULL and no function will be called.
See Add Response Header Field for further details.
CPU_BOOLEAN App_OnRespHdrTx (const HTTPs_INSTANCE *p_instance,
HTTPs_CONN *p_conn,
const void *p_hook_cfg);
.OnRespTokenHook#
Configure response dynamic token replacement hook function.
The hook function is called by the HTTP server when a token is found. Basically, the callback function must fill a buffer with the value to be sent instead of the token.
If the header feature is not enabled, this field is not used and can be set as DEF_NULL
.
See Get Token Value for further information.
CPU_BOOLEAN App_OnRespToken (const HTTPs_INSTANCE *p_instance,
HTTPs_CONN *p_conn,
const void *p_hook_cfg,
const CPU_CHAR *p_token,
CPU_INT16U token_len,
CPU_CHAR *p_val,
CPU_INT16U val_len_max);
.OnRespChunkHook#
Configure response chunked data hook function.
The hook function must be set up when the application needs to send data in chunked transfer encoding. In that case, the HTTP server core will call the hook when the response body is being built.
If the hook is not required by the upper application layer, it can be set as DEF_NULL
and no function will be called.
See On Response Chunk Hook for further details.
CPU_BOOLEAN App_OnRespChunk (const HTTPs_INSTANCE *p_instance,
HTTPs_CONN *p_conn,
const void *p_hook_cfg,
void *p_buf,
CPU_SIZE_T buf_len_max,
CPU_SIZE_T *p_tx_len);
.OnTransCompleteHook#
Configure HTTP Transaction complete hook function.
This hook function is called after an HTTP transaction has been completed. When the persistent connection mode is enabled, it is possible that the application needs to free some memory objects related to a transaction and this hook function is there for that.
If the hook is not required by the upper application layer, it can be set as DEF_NULL and no function will be called.
See On Transaction Complete Hook for further details.
void App_OnTransCmpl (const HTTPs_INSTANCE *p_instance,
HTTPs_CONN *p_conn,
const void *p_hook_cfg);
.OnErrHook#
Configure error hook function.
When an internal error occurred during the processing of a transaction a hook function can be called to change the behavior such as the status code and the page returned.
If the hook is not required by the upper application layer, it can be set as DEF_NULL and no function will be called.
See Connection Error for further details.
void App_OnErr (const HTTPs_INSTANCE *p_instance,
HTTPs_CONN *p_conn,
const void *p_hook_cfg,
HTTPs_ERR err);
.OnErrFileGetHook#
Configure Get error file hook function.
Get error file hook can be called every time an error has occurred when processing a transaction, i.e., status code is not equal to 'OK'. This function can set the web page that should be transmitted instead of the default error page defined in http-s_cfg.h.
If set to DEF_NULL the default error page will be used for every error.
See Get Error Document for further details.
void App_OnErrFileGet (const void *p_hook_cfg,
HTTP_STATUS_CODE status_code,
CPU_CHAR *p_file_str,
CPU_INT32U file_len_max,
HTTPs_BODY_DATA_TYPE *p_file_type,
HTTP_CONTENT_TYPE *p_content_type,
void **p_data,
CPU_INT32U *p_date_len);
.OnConnCloseHook#
Configure Connection close hook function.
Once a connection is closed a hook function can be called to let the upper application layer know that a connection is not yet active. This hook function could be used to free some previously allocated memory.
If the hook is not required by the upper application layer, it can be set as DEF_NULL and no function will be called.
See Connection Close for further details.
void App_OnConnClose (const HTTPs_INSTANCE *p_instance,
HTTPs_CONN *p_conn,
const void *p_hook_cfg);
HTTP Server Instance Header Configuration#
HTTP headers can be added to HTTP request and response messages to specify additional parameters for the HTTP transaction. See section Headers for more details on HTTP headers.
The HTTP Server module supports both reception and transmission of additional headers. However, note that some header fields are already taken care of by the HTTP Server stack and must therefore not be added by the application :
Host
Content-Type
Content-Length
Transfer-Encoding
Connection
Location
Two distinct structures are available to configure the request and response part. Therefore, header fields received have their own configuration as the headers fields to transmit an HTTP response. This allows more flexibility in customizing your own HTTP server application. For example, your server can be more interested in receiving many headers from clients and not adding any headers of its own in the HTTP response.
The Header configurations are part of the HTTP server Instance configuration and must be included in the HTTPs_CFG object (see section Instance Configuration ).
Fields Description#
Structure Field | Type | Description | Possible Values |
---|---|---|---|
.NbrPerConnMax | CPU_INT16U | Maximum number of headers for each HTTP request or response. | SHOULD be >= 1LIB_MEM_BLK_QTY_UNLIMITED to set an unlimited pool. |
.DataLenMax | CPU_INT16U | Maximum length of the header field value accepted by the HTTP server. | SHOULD be >= 1 |
Since the HTTP server only processed an HTTP Transaction at a time on a given Connection, the .NbrPerConnMax field set the number of headers available for an HTTP transaction and connection.
HTTP Server Instance Query String Configuration#
To enable the Query String feature, the compile-time configuration HTTPs_CFG_QUERY_STR_EN must be set accordingly (See section Module Configuration ).
Also a configuration object (HTTPs_QUERY_STR_CFG) MUST be added to the HTTP Instance configuration (See section Instance Configuration ).
For more information on HTTP Query String, see section Query String .
Fields Description#
Structure Field | Type | Description | Possible Values |
---|---|---|---|
.NbrPerConnMax | CPU_INT16U | Maximum number of Query String fields accepted for each HTTP request. | SHOULD be >= 1LIB_MEM_BLK_QTY_UNLIMITED to set an unlimited pool. |
.KeyLenMax | CPU_INT16U | Maximum length of the key part accepted by the HTTP server. | SHOULD be >= 1 |
.ValLenMax | CPU_INT16U | Maximum length of the value part accepted by the HTTP server. | SHOULD be >= 1 |
HTTP Server Instance Form Configuration#
To enable the Form feature, the compile-time configuration HTTPs_CFG_FORM_EN must be set accordingly (See section Module Configuration ).
Also a configuration object (HTTPs_FORM_CFG) MUST be added to the HTTP Instance configuration (See section Instance Configuration ).
For more information on HTTP Form Submission, see section HTTP Form .
Fields Description#
Structure Field | Type | Description | Possible Values |
---|---|---|---|
.NbrPerConnMax | CPU_INT16U | Maximum number of Form fields accepted for each HTTP request.Number must be greater than or equal to the maximum number of input fields which can be transmitted inside a received HTML form. | SHOULD be >= 1LIB_MEM_BLK_QTY_UNLIMITED to set an unlimited pool. |
.KeyLenMax | CPU_INT16U | Maximum length of the key part accepted by the HTTP server. | SHOULD be >= 1 |
.ValLenMax | CPU_INT16U | Maximum length of the value part accepted by the HTTP server. | SHOULD be >= 1 |
.MultipartEn | CPU_BOOLEAN | Enable/Disable Multipart Form support. | DEF_ENABLED or DEF_DISABLED |
.MultipartFileUploadEn | CPU_BOOLEAN | Enable/Disable File Upload feature inside Multipart Form.If File Upload feature is enabled, the web server will store the file received. If the feature is not enabled and a file is received the file will simply be dropped.File upload is not yet possible with the Static File System. | DEF_ENABLED or DEF_DISABLED |
.MultipartFileUploadOverWrEn | CPU_BOOLEAN | Enable/Disable File overwrite when file is uploaded to server.File overwrite must be enabled to allow a file to be received if the file already exists in the folder. | DEF_ENABLED or DEF_DISABLED |
.MultipartFileUploadFolderPtr | CPU_CHAR * | Configures the folder where the uploaded files will be stored.A folder name needs to be specified to indicate where the uploaded files will be save.If it is wished to save uploaded files directly in the root web directory, the name folder needs to be set as "\".I f uploaded files need to be saved inside a subfolder of the root web directory, the folder MUST already exist when the HTTP server tries to access it. | SHOULD be a string pointer |
HTTP Server Instance Token Configuration#
To enable the Dynamic Token Replacement feature, the compile-time configuration HTTPs_CFG_TOEKN_EN must be set accordingly (See section Module Configuration ).
Also a configuration object (HTTPs_TOKEN_CFG) MUST be added to the HTTP Instance configuration (See section Instance Configuration ).
Fields Description#
Structure Field | Type | Description | Possible Values |
---|---|---|---|
.NbrPerConnMax | CPU_INT16U | Maximum number of tokens accepted for each HTTP transaction. | SHOULD be >= 1LIB_MEM_BLK_QTY_UNLIMITED to set an unlimited pool. |
.ValLenMax | CPU_INT16U | Maximum length of the token replacement value accepted by the HTTP server. | SHOULD be >= 1 |
HTTP Server Programming Guide#
This section regroups topics to help developing a custom HTTP server application with the Micrium OS HTTP Server stack. Examples are include in many sub-sections.
HTTP Server Interface with File System#
Although the HTTP Server module can be used without a File System, when file operations are required by the HTTP server, Micrium OS File System module is needed. This will allow you to dynamically load the web pages and enable your web server to receive files. However, the HTTP Server comes with a minimalist in-house Static File system which only stores static files (stored in the code space memory). Obviously, it is only possible to read them and thus not possible to upload files to a web server when the static file system is used.
Configuration#
Compile-Time Configuration#
The configuration macro HTTPs_CFG_FS_PRESENT_EN must be set to DEF_ENABLED in the http_server_cfg.h
file when a File System (the in-house static or a standard FS) must be used with the HTTP server.
See section File System Compile-time Configuration for more details.
Run-Time Configuration#
Three types of configuration structure exist for the File System Configuration: one when No FS is used, one for the Static FS and one when Micrium OS File System is used. Depending on your setup, an object of one of those structures type must be defined in the application and passed as a pointer inside the instance configuration object structure (HTTPs_CFG).
See section File System Run-time Configuration for additional details.
Usage#
Transferring Files to Use with the HTTP Server#
Transferring files on the file system for use with the HTTP Server module is outside the scope of this document. For this purpose, you could use an FTP client, such as Micrium OS FTP Client , or alternatively, use a mass storage media to access your file system.
Note that the HTTP Server can support file upload when Micrium OS File System is used. Thus it’s possible to create scripts to transmit files using the POST method even if no file is yet loaded. Also, many web browsers now have plugins for testing purposes. They allow you to send custom HTTP requests to a server. You can therefore use some of those tools to upload files to the HTTP server. Micrium has tested the Postman plugin with Chrome.
Using the HTTP Server with the Static File System#
The HTTP Server provides a small file system that could allow it to be used without Micrium OS File System.
The static file system relies on C arrays to represent the various files, and those files are accessible only for reading. The HTTP Server ships with a very basic web page consisting of a .gif and two .html files.
A python script named GenerateFS.py is offered in the HTTP Server code allowing to convert files into C arrays. The script can be useful if many files are to be converted since it supports recursion inside a folder. The script also generates C files (generated_fs.c/.h) with the function to call to include all the C arrays generated.
This script has been created to ease your life as a developer. It is not intended to be a production tool.
The script should be called in a command line shell like shown below:
python GenerateFS.py [source directory or file name] [destination directory] -f |
---|
The first argument is the path directory where to files to be converted are located or the file name of the single file to convert. The second argument is the directory path where to save the generated file(s). An optional -f argument can be used to force the re-writing if the destination file already exists.
Static File System Module Configuration#
A configuration file will be created if you select a static file system in your project. The configuration file name is http_server_fs_port_static_cfg.h. Refer to Configuration for Static File System for more information.
HTTP Server Control Structures#
Many hook functions receive pointers to control structures which can be used by upper layer to change the behavior of the server and for debugging purpose.
HTTPs_INSTANCE#
The instance control structure should be only used for debugging purpose. The upper application MUST not modify this structure, it must only read data except for the .DataPtr field. Here is a list of fields of interest:
Field | Description |
---|---|
.Started | The HTTP Server instance is running or is stopped. |
.CfgPtr | Pointer to the instance's configuration. |
.SockListenID_IPv4 | Socket ID used to listen on server port for IPv4 socket family. |
.SockListenID_IPv6 | Socket ID used to listen on server port for IPv6 socket family. |
.ConActiveCtr | Current number of connection active. |
.StatsCtr | Pointer to instance statistics counter structure. |
.ErrsCtr | Pointer to instance errors counter structure. |
.DataPtr | This field is available for the upper application to store memory location relative to the instance that will be accessible across all hook functions. |
HTTPs_CONN#
The connection control structure may be used to change the behavior on a particular HTTP transaction occurring on a connection and for connection processing and debugging purpose.
Fields to Read#
Those are the relevant connection fields that can be read inside the hook functions by the application. They can, among others things, be used to demultiplex a connection:
.ClientAddr
Contains the IP address and port of the client.
.SockID
Contains the socket ID used to receive and transmit data.
.Method
This field contains the method of the request received:
HTTP_METHOD_GET
HTTP_METHOD_POST
HTTP_METHOD_HEAD
HTTP_METHOD_PUT
HTTP_METHOD_DELETE
.ReqContentType
If the HTTP request has a body, this field will contains the content type of the body.
.QueryStrListPtr
This field is the head of the list of key-value pairs received inside a Query String if one was present after the request URL.
.HdrListPtr
This field is the head of the list of header fields received inside the HTTP request.
.FormDataListPtr
This field is the head of the list of key-value pairs received in a form inside a POST request.
NULL, if no key-value pairs was received.
Fields to Read/Write#
The following is a list of field that can be modified via some hook functions:
.StatusCode
HTTP status code of the connection. When it changes, the web server transmits the response (status code and status phrase) with the status code of the connection. See section HTTP Server Recognized Status Codes for a list of Status Code recognized by the HTTP Server module.
.PathPtr
At the request level, this field contains the path to the resource received in the HTTP request URL. It can be used for comparison inside hooks to do some operations according to the URL received.
At the response level, if the resource is a file (see RespBodyDataType field), this field will be used to fetch the file from the File System whose location is indicated by the PathPtr. This file will then be copied in the response body. This field will also be used to construct the location header if necessary.
Before the response level, the upper application can modify the PathPtr contents via the hook functions if its needs to modify the file to send in the response. If the resource to send back in the response is not a file, the field can still be used to set the path of the resource in case a location header also needs to be sent.
The pointer MUST NOT be changed at any moment. Only the buffer content pointed by PathPtr can be modified to write a new string.
.DataPtr
In the case where the resource to send in the response is a file contained in a FS (RespBodyDataType == FILE), this field is used by the server to store the file data to transmit. Therefore, It MUST NOT be modified by the application.
In the case where the resource to send in the response is static data located in memory (RespBodyDataType == STATIC DATA), this field MUST be set by the application via the hook functions. It should be set the point to the data to send.
In the case where the resource to send is also data located in memory (RespBodyDataType == STATIC DATA) but that must be sent in Chunked Transfer Encoding with the Chunk Hook , the DataPtr MUST be set to NULL by the application via the hooks functions. That way the Chunk Hook will be called later.
.DataLen
In the case where the resource to send is a file contain in a FS (RespBodyDataType == FILE), this field will be used by the server to store the length of the file. Therefore, it MUST NOT be modified by the application via the hook functions.
In the case where the resource to send is static data located in memory (RespBodyDataType == STATIC DATA) and that the DataPtr was set to the memory address of the data, the DataLen field MUST be set to the data length by the application.
When transferring data via the Chunk Hook because the DataPtr was previously set to NULL, the DataLen field is not taken into account by the server.
.RespContentType
This field will contains the content type of the response body.
If a file (that is in a File System) is to be sent and the RespContentType field is set to "Unknown", the server will parse the file extension to set the Content Type. Therefore, the application could set the field via the hook functions, but doesn't need to in the case of a file.
If static data is to be sent (RespBodyDataType == STATIC DATA), this field MUST absolutely be set by the application via the hook functions.
.RespBodyDataType
This field set the type of data of the response body. Three types are available:
HTTPs_BODY_DATA_TYPE_FILE: When data body is from a file that was stored in a File System.
HTTPs_BODY_DATA_TYPE_STATIC_DATA: When data body is from memory allocation or is sent via Chunk Hook .
HTTPs_BODY_DATA_TYPE_NONE: When no body will be sent with the response.
By default this field is set to HTTPs_BODY_DATA_TYPE_FILE for GET and HEAD methods and to HTTPs_BODY_DATA_TYPE_NONE for POST, DELETE and PUT method. The field can be modified by the application via the hook functions.
.ConnDataPtr
This parameter is available for the upper application to store memory location for connection processing across all hook functions.
All other fields MUST NOT be modified but they could be read for the connection processing and for debugging. |
---|
We strongly recommend to use the three following API functions: HTTPs_RespBodySetParamFile () , HTTPs_RespBodySetParamStaticData() and HTTPs_RespBodySetParamNoBody() , to set the Response Body parameters adequately instead of changing the fields directly. Those functions will change the right fields for you according to the type of body you want to send. |
---|
HTTP Server Query String#
A Query String is a set of Key-Value pairs or single values added at the end of the request's URL after a question mark character "?". Each fields of the Query are separated by the "&" character.
For more details, see section Query String .
The HTTP Server can supports the reception of a Query String in the HTTP request.
Configuration#
Compile-Time Configuration#
The configuration macro HTTPs_CFG_QUERY_STR_EN must be set to DEF_ENABLED in the http_server_cfg.h file to enable this feature.
See section Query String Configuration for more details.
Run-Time Configuration#
The run-time configuration for Query String is defined as a HTTPs_QUERY_STR_CFG structure. Your application must declare an HTTPs_QUERY_STR_CFG object and include a pointer to this object in the HTTP server instance configuration HTTPs_CFG object where the QueryStrCfgPtr parameter is defined.
See section Query String Configuration for additional details.
Hook Function#
The HTTP Server Instance configuration structure (HTTPs_CFG) contains a pointer to an HTTPs_HOOK_CFG object. This object indexes all the hook functions required by your application.
For additional details on the configuration of hook functions, see section Hook Configuration .
To visualize when each hook function is called by the HTTP server core, see section Hook Functions .
To retrieve the Query String data saved by the HTTP server, two hook functions can be used: OnReqHook and OnReqRdySignalHook .
Usage#
When the feature is enabled, query strings received in an HTTP request are saved by the HTTP server core under a list of key-value pair. This list is available using the field .QueryStrListPtr inside the HTTPs_CONN structure. This list is accessible to your application inside the hook functions OnReqHook and OnReqRdySignalHook.
Single value fields inside the Query String are also supported. The value will still be saved in a Key-Value pair block, but only the value field will be meaningful.
HTTP Server Hook Functions#
Each Web server is highly customizable using hook functions. Many hook functions can be called by the HTTP Server module during the processing of each client's request. Those hook functions allow the application to respond differently based on the application context. For example, it's possible to implement functionality such as dynamic content replacement, authentication, adding HTTP headers to the HTTP response (i.e., cookie), redirect, generate run-time data page, etc.
For more information on how to configure the hook functions for a given HTTP server instance, see the section Hook Configuration .
Also for the complete list of all the hook functions available and their prototype, see the section Hook Functions API .
HTTP Tasks Global Overview#
The diagrams below show a simplified state diagram of the HTTP server transaction processing but also when and where the hook functions are called.
HTTP Request Processing#
The diagrams below shows in more detail the HTTP received request processing section.
HTTP Response Processing#
The diagrams below show in more details the HTTP response processing section.
HTTP Server Header Fields#
The Header Field feature allows the HTTP Server module to receive and transmit additional HTTP headers to the one already processed internally by the HTTP server core.
The header fields listed below are already taken care of by the HTTP Server stack and must therefore not be added or processed by the application:
Host
Content-Type
Content-Length
Transfer-Encoding
Connection
Location
See section HTTP Header Fields Recognized for a list of all the header field recognized by the HTTP Server product.
To learn more on the HTTP header concepts, see section Headers .
Configuration#
For the HTTP server to support processing of additional headers, two types of configuration must be set up: the compile-time and the run-time configuration. Also, some hook functions must be defined to allow the upper application to use this feature.
The Header Field feature is divided in two independent parts: the reception and the transmission. Each part has its own configuration as it will be shown below.
The reception is associated with HTTP header fields received in HTTP requests and the transmission is associated with HTTP header fields to send in HTTP responses.
Compile-time Configuration#
Two configuration macros are available for the Header Field feature: HTTPs_CFG_HDR_RX_EN for the reception and HTTPs_CFG_HDR_TX_EN for the transmission. Each can be enabled and disabled separately.
See section Header Field Configuration for more details.
Run-time Configuration#
The run-time configuration for the Header Field feature has defined two structures: HTTPs_HDR_RX_CFG and HTTPs_HDR_TX_CFG. If your application needs to save headers received in HTTP requests, it must declare an HTTPs_HDR_RX_CFG object and include a pointer to this object in the HTTP server instance configuration HTTPs_CFG object where the HdrRxCfgPtr parameter is defined. The same must be done with an HTTPs_HDR_TX_CFG object if your application wishes to add headers to HTTP responses. The HdrTxCfgPtr parameter of the HTTPs_CFG object must therefore be defined.
See section HTTP Header Configuration for additional details.
Hook Function#
The general HTTP Server Instance configuration structure (HTTPs_CFG) contains a pointer to an HTTPs_HOOK_CFG object. This object indexes all the hook functions required by your application.
For additional details on the configuration of hook functions, see section Hook Configuration .
To visualize when each hook function is called by the HTTP server core, see section Hook Functions .
In reception, the hook OnReqHdrRxHook() can be used to set which header field the application wishes to keep.
In transmission, the hook OnRespHdrTxHook() can be used to add a header field to the header list that the server will use to construct the HTTP response to send.
Usage#
Reception#
Once a HTTP request is received by the HTTP server, the server will call, if defined, the OnReqHdrRxHook() for each header fields received. The upper application must implement this hook to the return status DEF_YES when the header field must be saved and DEF_NO otherwise.
Transmission#
When the server is constructing an HTTP response to send, it will call the hook function OnRespHdrTxHook() when adding headers to the response. In this hook, the upper application can add header fields to the HTTP headers list by using the API function HTTPs_RespHdrGet(). This function will find a Header Field block available in the pool and add it to the list. The upper application just needs to fill the block fields afterwards.
HTTP Server Request Body Data#
The HTTP Server module has the capacity to parse forms received in a POST request body when the Form feature is enabled on the server instance. For more information, see section Form .
Forms are the only body parsing integrated in the server core. For your application to retrieve the body data of other requests (or even form's data when the feature is disabled) the server offers a hook function: On Request Body Received Hook .
CPU_BOOLEAN HTTPs_ReqBodyRxHook (const HTTPs_INSTANCE *p_instance,
HTTPs_CONN *p_conn,
const void *p_hook_cfg,
void *p_buf,
const CPU_SIZE_T buf_size,
CPU_SIZE_T *p_buf_size_used);
This hook, if defined, will be called by the HTTP server each time new data is received in the server's internal buffer. With this hook function, the application has the liberty to copy the data received or to read it directly in the HTTP buffer to retrieve only the information needed. The application doesn't have the obligation to read all the data contained in the buffer. It MUST return the length of the data that was read (p_buf_size_used) and therefore, the next time around, the data not read will still be in the reception buffer. If the application doesn't want to receive more data, it can return DEF_NO at any time and data received afterward will be dropped by the server.
HTTP Server Form#
The HTTP Server module supports HTML form submissions through the POST method. The following POST Internet media type are supported:
"application/x-www-form-urlencoded" is the default format for encoding key-value pairs when a web browser sends a POST request from a web form element.
"multipart/form-data" is the format that must be used when uploading large amount of data such as a file on a web server.
For more information on HTML Forms, see section HTTP Form.
Configuration#
For the HTTP server to support processing of incoming form submissions, two types of configuration must be set up: the compile-time and the run-time configuration. Also, some hook functions must be defined to allow the application to retrieve the data received in the form.
Compile-time Configuration#
Two compile-time configuration macros are available for the form submissions: HTTPs_CFG_FORM_EN and HTTPs_CFG_FORM_MULTIPART_EN.
The first macro, if set to DEF_ENABLED, enables the Form feature and all the functions and data associated with it. Moreover, if the multipart form must be supported the second macro should also be enabled.
See section Module Configuration for more details.
Run-time Configuration#
The run-time configuration for Form submission is defined as a HTTPs_FORM_CFG structure. Your application must declare an HTTPs_FORM_CFG object and include a pointer to this object in the HTTP server instance configuration HTTPs_CFG object where the FormCfgPtr parameter is defined.
See section HTTP Form Configuration for additional details.
Hook Functions#
The general HTTP Server Instance configuration structure (HTTPs_CFG) contains a pointer to an HTTPs_HOOK_CFG object. This object indexes all the hook functions required by your application.
For additional details on the configuration of hook functions, see section Hook Configuration.
To visualize when each hook function is called by the HTTP server core, see section Hook Functions.
The hook function OnReqRdySignalHook()
can be used to access the data received inside the form. The data is located under a list of key-value pairs (parameter FormDataListPtr) inside the HTTPs_CONN object. If a lot of processing must be done with the data received, it is recommend not to do it inside the OnReqRdySignalHook()
hook because it will slow down all the other connection processing. Instead, the OnReqRdySignalHook()
hook should be used to signal another task that the data was received and is ready to be processed. In that case, the hook function OnReqRdyPollHook () should be used to indicate to the server when the data processing is completed. When defined, the server will call the OnReqRdyPollHook () hook until the function returns the status Ok to indicate that the processing is finished.
Usage#
When the form is posted, the web server will process the POST action and will invoke the callback with a list of key-value pairs transmitted.
Assuming the HTML page that look like this:
Listing - HTML Page Example Application Form#
<html>
<body>
<form action="form_return_page.htm" method="post">
Text Box 1: <input type="text" name="textbox1" />
Text Box 2: <input type="text" name="textbox1" />
<input type="submit" name="submit" value="Submit"></input>
</form>
</body>
</html>
The HTTP server core will receive the POST request and save the form data inside a key-value pairs list (FormDataListPtr parameter of the HTTPs_CONN structure). The server will then call the hook function OnReqRdySignalHook() (of the HTTPs_HOOK_CFG object inside the HTTPs_CFG object) to allow the application to retrieve and process the data received. The key-value pairs inside the list will be:
Key: "textbox1", Value: "Text Box 1 value"
Key: "textbox2", Value: "Text Box 2 value"
Key: "submit", Value: "Submit"
Since all connections are processing within only one task it is very important that all hook functions are non-blocking and can be executed quickly.
If the upper application takes a while to complete the data processing, the upper application should implement a task where the data can be process. The task should be polled to know if the processing is completed with the OnReqRdyPollHook () hook.
Uploading files using the HTTP Server#
It is possible to use a HTML form to upload files on the file system using the HTTP Server. The following listing shows an example of HTML code that can be used to implement that functionality:
Listing - HTML Page Example Multipart Form#
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">
<html>
<head>
<title>File Upload</title>
</head>
<body>
<form action="File_Upload.htm"
ENCTYPE="multipart/form-data"
method="post">
<p><b>Choose The file To Upload:</b>
<input type="file" name="file_form_field_name" ></input></p>
<p><input type="submit" name="Submit" value="Submit"></input></p>
</form>
</body>
</html>
Multipart form type must absolutely be specified in the form tag. For example: |
---|
When the file upload feature is enabled (parameter MultipartFileUploadEn inside the run-time configuration), the HTTP Server instance writes the file to the default location specified by the run-time configuration. If no error occurred when writing the file a key-value pair will be added to the list to specify the HTML control name of the field and the absolute location of the uploaded file. Thus, the upper application can easily retrieve or even move any file transmitted when the OnReqRdySignalHook() function is called. For example, for the upper listing, the key value pair list will contain the following:
Key: "file_form_field_name", Value: "||Path|RemoteFileName.html"
Key: "submit", Value: "Submit"
If an error occurs during the file transfer such as inability to open or write the file, the OnReqRdySignalHook()
function is not called, and the upper application is notified by the Error hook function.
Note that the file upload is not possible using the static file system.
HTTP Server Response Body Data#
To configure and edit the response body data, the HTTP Server module offers three API functions:
HTTPs_RespBodySetParamFile() | This function can be used to transmit in the response body a file contained in a File System (a standard FS or the HTTP Static FS) . See section Specify File to Send in Response Body . |
---|---|
HTTPs_RespBodySetParamStaticData() | This function can be used to transmit data contained in an application buffer or also to specify that the data should be sent with the Chunked Transfer Encoding. See sections Send data contained in Application Buffer and Send data with the Chunk Hook . |
HTTPs_RespBodySetParamNoBody() | This function can be used to specify that no body should be added in the HTTP response. |
Those three API functions should be used by the upper application inside one of two hook functions: Connection Request and Request Ready Signal .
Specify File to Send in Response Body#
|
---|
Send data contained in Application Buffer#
|
---|
Send data with the Chunk Hook#
|
---|
HTTP Server Token Replacement#
The HTTP Server module allows dynamic content to be inserted in HTML and plain text documents by using special tokens being substituted before the page is actually sent to the web browser. There are two type of token: internal and external. The value of external token must be provided by the upper application via a hook function. Internal tokens are defined to print some data related to HTTP such as status lines and error codes.
Configuration#
Compile-time Configuration#
The macro configuration HTTPs_CFG_TOKEN_PARSE_EN inside the http_server_cfg.h file must be set to DEF_ENABLED to enable the token substitution feature.
See section Dynamic Content Configuration for more details on compile-time configuration.
Run-time Configuration#
The run-time configuration for Token Replacement is defined as a HTTPs_TOKEN_CFG structure. Your application must declare an HTTPs_TOKEN_CFG object and include a pointer to this object in the HTTP server instance configuration HTTPs_CFG object where the TokenCfgPtr parameter is defined.
See section Token Configuration for additional details.
Hook Configuration#
The HTTP Server Instance configuration structure (HTTPs_CFG) contains a pointer to an HTTPs_HOOK_CFG object. This object indexes all the hook functions required by your application.
For additional details on the configuration of hook functions, see section Hook Configuration .
To visualize when each hook function is called by the HTTP server core, see section Hook Functions .
The hook function OnRespTokenHook() must be used to set the value that will be used to replace the token found. Each time a token is found in the HTML/text file, the hook function will be called.
Usage#
External Token#
External tokens are represented in the HTML/text files as:
${TOKEN_NAME}
Assuming we have an HTML page that look like this:
<html><body><center> This system's IP address is ${My_IP_Address} </center></body></html>
When a web client requests this file, the HTTP Server will parse the file, find ${My_IP_Address} token, and pass the string "My_IP_Address" into the OnRespTokenHook() hook function. That function will copy the token value then the HTTP Server instance will send the token value instead of the token:
<html><body><center> This system's IP address is 135.17.115.215 </center></body></html>
Note that if the upper application doesn’t copy a valid data, the token is automatically replaced by ‘~’ characters. See Response Token Transmit Hook for more information on how the callback function has to be implemented to support this.
Internal Token#
Internal tokens are represented in the HTML files as:
#{TOKEN_NAME}
For every HTML document that must be transmitted, the HTTP Server parses the document and replaces all internal tokens automatically without calling any callback function. Internal token can be use in any HTML/text documents. Here is the list of built-in token replacement:
Token | Value |
---|---|
#{STATUS_CODE} | Replaced by status code number of the connection. |
#{REASON_PHRASE} | Replaced by the reason phrase based on the status code of the connection |
HTTP Server Proxy#
The HTTP Server module can be accessed behind a proxy. When an HTTP Server is behind a HTTP Proxy, the HTTP client must send its requests using an absolute URI. For example,
GET http://example.com/index.html HTTP/1.1
When the absolute URI feature is enable, the HTTP server will support absolute URI in the first line of the HTTP request messages.
The server will also look for the Host header field in the received request messages and save it in the .HostPtr field of the HTTPs_CONN structure.
HTTP Server Add-on#
The HTTP Server module offers different add-on to simplify complex HTTP server application development.
Add-on Module | Description |
---|---|
The Control Layer is a module bound to the HTTP Server by its hook functions and used to manage multiple groups of authentication process and application process. | |
This module basically implements an authentication and authorization process based on the HTTP cookie header. It is made to work with the Control Layer only. | |
This module was created to facilitate the development of RESTful applications. Its allows you to create REST resources based on a specific URL. Each resource has its own set of hook functions with a different hook for each HTTP method. It can be used with or without the Control Layer module. |
HTTP Server Control Layer#
Introduction#
The control layer is a module bound to the HTTP Server used to manage multiple groups of authentication process and application process. There are many cases where one would like to have multiple functions bound to the same hook but with different goals. This is a the role of the Control layer.
The control layer maps each hook function available in the HTTP Server on its own hook. The configuration of those hooks has two layers: The Authentications and the Applications.
It provides an abstraction over the HTTPs_CONN's and HTTPs_INSTANCE's contextual data holders: p_instance->DataPtr and p_conn->ConnDataPtr. The Control Layer will automatically substitute them. Those contextual information are saved after each hook call and restored before each hook call. Which means that each Control Layer instance has its own connection and instance data pointers. The following diagram shows these context switches through color variance:
Authentications#
The Authentications layer is the part of the configuration where one can specify how to hide an application, e.g., put your application behind a Login form. Each Control Layer configuration can have a list of authentications which must succeed in order to access any application of the same configuration.
Listing - Authentication structure#
typedef struct https_ctrl_layer_auth_hooks {
HTTPs_INSTANCE_INIT_HOOK OnInstanceInit;
HTTPs_REQ_HDR_RX_HOOK OnReqHdrRx;
HTTPs_REQ_HOOK OnReqAuth;
HTTPs_RESP_HDR_TX_HOOK OnRespHdrTx;
HTTPs_TRANS_COMPLETE_HOOK OnTransComplete;
HTTPs_CONN_CLOSE_HOOK OnConnClose;
} HTTPs_CTRL_LAYER_AUTH_HOOKS;
typedef struct https_ctrl_layer_auth_inst {
HTTPs_CTRLLAYER_AUTH_HOOKS *HooksPtr;
void *HooksCfgPtr;
} HTTPs_CTRL_LAYER_AUTH_INST;
Therefore, for a given Control Layer configuration, many Authentication modules can be defined. Each module must declared its own HTTPs_CTRL_LAYER_AUTH_INST object that regroups a pointer to its own hook configuration (HTTPs_CTRL_LAYER_AUTH_HOOKS object) and a pointer to other configurations required by the module if necessary (See section HooksCfgPtr Parameter ).
Applications#
The Application layer is the part where HTTP requests can be analyze and HTTP responses will be built. At this point, the authentications required have passed already. The application layer handles both body parsing and body formatting. The application has full control over the HTTP Server response and is called every time the server needs to poll the hook to complete its task.
Listing - Application structures#
typedef struct https_ctrl_layer_app_hooks {
HTTPs_INSTANCE_INIT_HOOK OnInstanceInit;
HTTPs_REQ_HDR_RX_HOOK OnReqHdrRx;
HTTPs_REQ_HOOK OnReq;
HTTPs_REQ_BODY_RX_HOOK OnReqBodyRx;
HTTPs_REQ_RDY_SIGNAL_HOOK OnReqSignal;
HTTPs_REQ_RDY_POLL_HOOK OnReqPoll;
HTTPs_RESP_HDR_TX_HOOK OnRespHdrTx;
HTTPs_RESP_TOKEN_HOOK OnRespToken;
HTTPs_RESP_CHUNK_HOOK OnRespChunk;
HTTPs_TRANS_COMPLETE_HOOK OnTransComplete;
HTTPs_ERR_HOOK OnError;
HTTPs_CONN_CLOSE_HOOK OnConnClose;
} HTTPs_CTRL_LAYER_APP_HOOKS;
typedef struct https_ctrl_layer_app_inst {
HTTPs_CTRL_LAYER_APP_HOOKS *HooksPtr;
void *HooksCfgPtr;
} HTTPs_CTRL_LAYER_APP_INST;
As for the Authentication Layer, a given Control Layer configuration can have many Application modules. each module must declared its own HTTPs_CTRL_LAYER_APP_INST object that regroups a pointer to its own hook configuration (HTTPs_CTRL_LAYER_APP_HOOKS object) and a pointer to other configurations required by the module if necessary (See section HooksCfgPtr Parameter ).
Configuration#
Demystify the HooksCfgPtr Parameter#
The HooksCfgPtr parameter will be passed as argument with each hook function from HooksPtr. Therefore, HooksCfgPtr parameter is offered to pass information necessary to specify the behavior of a given authentication instance or application instance. This information highly depends on the instance nature. If not necessary, the HooksCfgPtr parameter can be set to DEF_NULL.
HTTPs_CTRL_LAYER_CFG and HTTPs_CTRL_LAYER_CFG_LIST#
The control layer takes an HTTPs_CTRL_LAYER_CFG_LIST structure pointer as configuration. Below is the definition of the structures for the configuration of the Control Layer:
Listing - HTTPs_CTRLL_CFG and HTTPs_CTRLL_CFG_LIST#
/* Controlled service layer. */
typedef struct https_ctrl_layer_cfg {
HTTPs_CTRL_LAYER_AUTH_INST **AuthInstsPtr;
CPU_SIZE_T AuthInstsNbr;
HTTPs_CTRL_LAYER_APP_INST **AppInstsPtr;
CPU_SIZE_T AppInstsNbr;
} HTTPs_CTRL_LAYER_CFG;
/* List of controlled services. */
typedef struct https_ctrl_layer_cfg_List {
HTTPs_CTRL_LAYER_CFG **CfgsPtr;
CPU_SIZE_T Size;
} HTTPs_CTRL_LAYER_CFG_LIST;
Here's an example how to declare a Control Layer configuration:
Listing - Control layer config example#
/* Define some authentication hook set. */
HTTPs_CTRL_LAYER_AUTH_HOOKS AuthHooks = { ... };
/* Create an auth instance based on the hook set and a user config pointer */
HTTPs_CTRL_LAYER_AUTH_INST AuthInst = { &AuthHooks, ... };
/* Define some application hook set */
HTTPs_CTRL_LAYER_APP_HOOKS SomeAppHooks = { ... };
/*Create an app instance based on the hook set and a user config pointer */
HTTPs_CTRL_LAYER_APP_INST SomeAppInst = { &SomeAppHooks, ... };
/* List both authentications and applications */
HTTPs_CTRL_LAYER_AUTH_INST *AuthInsts[] = { &AuthInst };
HTTPs_CTRL_LAYER_APP_INST *AppInsts[] = { &SomeAppInst };
/* Create a config for the control layer */
HTTPs_CTRL_LAYER_CFG SomeCfg = {
authInsts,
sizeof(authInsts) / sizeof(HTTPs_CTRL_LAYER_AUTH_INST *),
appInsts,
sizeof(appInsts) / sizeof(HTTPs_CTRL_LAYER_APP_INST *),
};
/* List the configurations. */
HTTPs_CTRL_LAYER_CFG *CtrlLayerCfgs[] = { &SomeCfg };
/* Build the cfg structure for the control layer */
HTTPs_CTRL_LAYER_CFG_LIST CtrlLayerCfgList= {
CtrlLayerCfgs,
sizeof(CtrlLayerCfgs) / sizeof(HTTPs_CTRL_LAYER_CFG *)
};
HTTP Server Hook Binding#
Here's an example of how to bind it to an HTTPs_CFG:
Listing - HTTPs_CFG using ControlLayer#
const HTTPs_CFG foo = {
...,
/*
*--------------------------------------------------------------------------------------------------------
* HOOKS CONFIGURATION
*--------------------------------------------------------------------------------------------------------
*/
/* Declared in HTTP/Server/Add-on/CtrlLayer/http-s_ctrl_layer.h */
&HTTPsCtrlLayer_HookCfg, /* .HooksPtr */
/* Previously declared in the configuration section */
&CtrlLayerCfgList, /* .Hooks_CfgPtr */
...
};
HTTP Server Authentication module#
Introduction#
The HTTP Server authentication system is built on top of the Control Layer. Without the control layer it wont work. It also requires the Authentication module of the Micrium OS Common libraries that defines the User Management.
There is two subsystems for this module: The Control Layer Authentication Layer and the Control Layer Application Layer.
Authentication Layer : Cookie Checker
The cookie checker is basically a Control Layer instance bound to the Authentication layer. When a request is made without a valid cookie, it refuses to let it go and will take on the request. When a cookie is present and valid, the request is then checked to know which rights are required to continue. If the user bound to the cookie provided has the rights to continue, the request is marked as accepted.
Application Layer#
Unprotected Requests: Cookie Creator
The cookie creator work after the cookie checker has done it's work and could not find a valid cookie. In that case, if the request is a POST with the "logme form", the request is "catched" and the parsed body is inspected to find a username and a password.This happens at the application phase of the Control Layer. If a username and a password is found within the request, it is then validated with known credentials from the user management layer. If a valid match is found, a session is created, the user is associated with it, and the cookie identifier is sent to the HTTP client.
Protected Requests#
Once the session was created, requests related to log in should not occurred, but for safety the Authentication module will still "catched" them. A request to the login page will be redirect to the default page. A POST request with the "logme form" will be parsed even though a session is already existing and if the credentials are incorrect the session will be terminated.
Session Timeout#
The Authentication module also configures a timer to periodically check if any created sessions have timed out. After a session timed out, a cookie received with the session ID number will be considered invalid and any not authorized requests will be redirect to the configured page for unauthorized requests.
How to Configure#
To configure the HTTP Server authentication, here are the steps to follow:
Create users with their appropriate credentials and rights.
Define an hook function which will return the right necessary to process a given request.
Define an hook function which will check the requests received for a log in request but also set the pages for redirection for all of those requests.
Define an hook function which will check the requests received for a log out request.
Create the appropriate configurations and bind those three hook functions.
Bind those configurations to their respective Control Layer Instance configuration.
Use the three instances created in the Control Layer configuration.
Hook Functions#
Get Required Rights Hook#
This hook will be called by the Authentication Layer of the Control Layer when a request is received to check with the upper application what rights are associated with this request.
AUTH_RIGHT HTTPsAuth_GetRequiredRightsHook (const HTTPs_INSTANCE *p_instance,
const HTTPs_CONN *p_conn);
Login Hook#
This hook will be called by the Application Layer of the Control Layer to found requests related to the log in process, e.g., the GET requests for the resources of the log in page (html, css, images) and the POST request with the form log in. This hook functions will be called at two occasions : when the URL and headers of the request were received and parse by the server (state HTTPs_AUTH_STATE_REQ_URL), and also when the request body was received and parse (state HTTPs_AUTH_STATE_REQ_COMPLETE).
CPU_BOOLEAN AppGlobal_Auth_ParseLoginHook (const HTTPs_INSTANCE *p_instance,
const HTTPs_CONN *p_conn,
HTTPs_AUTH_STATE state,
HTTPs_AUTH_RESULT *p_result);
Logout Hook#
This hook will be called by the Application Layer of the Control Layer
CPU_BOOLEAN AppGlobal_Auth_ParseLogoutHook (const HTTPs_INSTANCE *p_instance,
const HTTPs_CONN *p_conn,
HTTPs_AUTH_STATE state);
Example#
The output of the "How to" steps should look like the example provided:
Listing - Authentication Functions Examples#
/*
*********************************************************************************************************
* AppGlobal_UsersInit()
*
* Description : Adds three users to the authentication system.
*
* Argument(s) : None.
*
* Return(s) : DEF_OK, if users initialization was successful.
* DEF_FAIL, otherwise.
*
* Note(s) : None.
*********************************************************************************************************
*/
CPU_BOOLEAN AppGlobal_UsersInit(void)
{
AUTH_USER admin;
AUTH_USER user;
AUTH_RIGHT right;
RTOS_ERR err_auth;
CPU_BOOLEAN result;
result = Auth_Init(&err_auth);
if (result != DEF_OK) {
return (DEF_FAIL);
}
result = Auth_CreateUser("admin",
"password",
&admin,
&err_auth);
if (result != DEF_OK) {
return (DEF_FAIL);
}
right = (HTTP_USER_ACCESS | AUTH_RIGHT_MNG);
result = Auth_GrantRight(right,
&admin,
&Auth_RootUser,
&err_auth);
if (result != DEF_OK) {
return (DEF_FAIL);
}
result = Auth_CreateUser("user0",
"",
&user,
&err_auth);
if (result != DEF_OK) {
return (DEF_FAIL);
}
result = Auth_GrantRight(HTTP_USER_ACCESS,
&user,
&admin,
&err_auth);
if (result != DEF_OK) {
return (DEF_FAIL);
}
result = Auth_CreateUser("user1",
"user1",
&user,
&err_auth);
if (result != DEF_OK) {
return (DEF_FAIL);
}
result = Auth_GrantRight(HTTP_USER_ACCESS,
&user,
&admin,
&err_auth);
if (result != DEF_OK) {
return (DEF_FAIL);
}
return (DEF_OK);
}
/*
*********************************************************************************************************
* AppGlobal_Auth_GetRequiredRightsHook()
*
* Description : Returns the rights required to fulfill the needs of a given request.
*
* Argument(s) : p_instance Pointer to the HTTP server instance object.
*
* p_conn Pointer to the HTTP connection object.
*
* Return(s) : returns the authorization right level for this example application.
*
* Note(s) : none.
*********************************************************************************************************
*/
AUTH_RIGHT AppGlobal_Auth_GetRequiredRightsHook (const HTTPs_INSTANCE *p_instance,
const HTTPs_CONN *p_conn)
{
return (HTTP_USER_ACCESS);
}
/*
*********************************************************************************************************
* AppGlobal_Auth_ParseLoginHook()
*
* Description : (1) Check the HTTP requests received to see if they are related to resources of the login page.
* (a) Check if the POST login is received.
* (b) For each request set the redirect paths on no, invalid & valid credentials.
* (c) Parse the form fields received in the body for the user and password.
*
*
* Argument(s) : p_instance Pointer to the HTTP server instance object.
*
* p_conn Pointer to the HTTP connection object.
*
* state State of the Authentication module:
* HTTPs_AUTH_STATE_REQ_URL: The URL and the headers were received and parse.
* HTTPs_AUTH_STATE_REQ_COMPLETE: All the request (URL + headers + body)
* was received and parse.
*
* p_result Pointer to the authentication result structure to fill.
*
* Return(s) : DEF_YES, if the request is the POST login.
* DEF_NO, otherwise.
*
* Note(s) : (2) This hook will be called twice for a request processed by the Authentication module:
* (a) When the Start line of the request (with the URL) and the headers have been
* received and parse -> HTTPs_AUTH_STATE_REQ_URL state.
* (b) When all the request has been completely received and parse including the body
* -> HTTPs_AUTH_STATE_REQ_COMPLETE state.
*
* (3) for each request received the redirect paths is set as follow:
* (a) RedirectPath_OnValidCred INDEX_PAGE_URL
* (b) RedirectPath_OnInvalidCred LOGIN_PAGE_URL
* (c) RedirectPath_OnNoCred
* (1) if the path is an unprotected path, let it go. (DEF_NULL) (i.e., the logo)
* (2) otherwise LOGIN_PAGE_URL
*********************************************************************************************************
*/
CPU_BOOLEAN AppGlobal_Auth_ParseLoginHook (const HTTPs_INSTANCE *p_instance,
const HTTPs_CONN *p_conn,
HTTPs_AUTH_STATE state,
HTTPs_AUTH_RESULT *p_result)
{
CPU_INT16S cmp_val;
CPU_BOOLEAN is_login = DEF_NO;
#if (HTTPs_CFG_FORM_EN == DEF_ENABLED)
HTTPs_KEY_VAL *p_current;
CPU_INT16S cmp_val_username;
CPU_INT16S cmp_val_password;
#endif
p_result->UsernamePtr = DEF_NULL;
p_result->PasswordPtr = DEF_NULL;
/* Set redirect paths for each requests. */
p_result->RedirectPathOnInvalidCredPtr = LOGIN_PAGE_URL;
p_result->RedirectPathOnValidCredPtr = INDEX_PAGE_URL;
switch (state) {
/* ----------- REQUEST URL RECEIVED ---------- */
case HTTPs_AUTH_STATE_REQ_URL:
/* Set redirect paths for each requests. */
cmp_val = Str_Cmp(p_conn->PathPtr, LOGIN_PAGE_URL);
if (cmp_val != 0) {
cmp_val = Str_Cmp(p_conn->PathPtr, MICRIUM_LOGO_URL);
if (cmp_val != 0) {
cmp_val = Str_Cmp(p_conn->PathPtr, MICRIUM_CSS_URL);
}
}
p_result->RedirectPathOnNoCredPtr = (cmp_val == 0) ? DEF_NULL : LOGIN_PAGE_URL;
/* Check if POST login received. */
cmp_val = Str_Cmp(p_conn->PathPtr, LOGIN_PAGE_CMD);
if (cmp_val == 0) {
is_login = DEF_YES;
}
break;
/* ---------- REQUEST BODY RECEIVED ---------- */
case HTTPs_AUTH_STATE_REQ_COMPLETE:
#if (HTTPs_CFG_FORM_EN == DEF_ENABLED)
/* Parse form fields received for user/pass. */
p_current = p_conn->FormDataListPtr;
while ((p_current != DEF_NULL) &&
((p_result->UsernamePtr == DEF_NULL) ||
(p_result->PasswordPtr == DEF_NULL))) {
if (p_current->DataType == HTTPs_KEY_VAL_TYPE_PAIR) {
cmp_val_username = Str_CmpIgnoreCase_N(p_current->KeyPtr,
FORM_USERNAME_FIELD_NAME,
p_current->KeyLen);
cmp_val_password = Str_CmpIgnoreCase_N(p_current->KeyPtr,
FORM_PASSWORD_FIELD_NAME,
p_current->KeyLen);
if (cmp_val_username == 0) {
p_result->UsernamePtr = p_current->ValPtr;
is_login = DEF_YES;
} else if (cmp_val_password == 0) {
p_result->PasswordPtr = p_current->ValPtr;
}
}
p_current = p_current->NextPtr;
}
#endif
break;
default:
break;
}
return (is_login);
}
/*
*********************************************************************************************************
* AppGlobal_Auth_ParseLogoutHook()
*
* Description : Parse requests received for logout URL and form data logout info.
*
* Argument(s) : p_instance Pointer to HTTPs instance object.
*
* p_conn Pointer to HTTPs connection object.
*
* state State of the Authentication module:
* HTTPs_AUTH_STATE_REQ_URL: The URL and the headers were received and parse.
* HTTPs_AUTH_STATE_REQ_COMPLETE: All the request (URL + headers + body) w
* as received and parse.
*
* Return(s) : DEF_YES, if Logout received.
* DEF_NO, otherwise.
*
* Caller(s) : AppGlobal_AppInst_AuthCfg.
*
* Note(s) : (1) This hook will be called twice for a request processed by the Authentication module:
* (a) When the Start line of the request (with the URL) and the headers have been
* received and parse -> HTTPs_AUTH_STATE_REQ_URL state.
* (b) When all the request has been completely received and parse including the body
* -> HTTPs_AUTH_STATE_REQ_COMPLETE state.
*********************************************************************************************************
*/
CPU_BOOLEAN AppGlobal_Auth_ParseLogoutHook (const HTTPs_INSTANCE *p_instance,
const HTTPs_CONN *p_conn,
HTTPs_AUTH_STATE state)
{
CPU_BOOLEAN is_logout = DEF_NO;
#if (HTTPs_CFG_FORM_EN == DEF_ENABLED)
HTTPs_KEY_VAL *p_current;
CPU_INT16S cmp_val;
#endif
switch (state) {
/* ----------- REQUEST URL RECEIVED ---------- */
case HTTPs_AUTH_STATE_REQ_URL:
/* Check if POST logout received. */
cmp_val = Str_Cmp(p_conn->PathPtr, LOGOUT_PAGE_CMD);
if (cmp_val == 0) {
is_logout = DEF_YES;
}
break;
/* ---------- REQUEST BODY RECEIVED ---------- */
case HTTPs_AUTH_STATE_REQ_COMPLETE:
#if (HTTPs_CFG_FORM_EN == DEF_ENABLED)
/* Parse form fields received for logout. */
p_current = p_conn->FormDataListPtr;
while (p_current != DEF_NULL) {
if (p_current->DataType == HTTPs_KEY_VAL_TYPE_PAIR) {
cmp_val = Str_CmpIgnoreCase_N(p_current->KeyPtr,
FORM_LOGOUT_FIELD_NAME,
p_current->KeyLen);
if (cmp_val == 0) {
is_logout = DEF_YES;
break;
}
}
p_current = p_current->NextPtr;
}
#endif
break;
default:
break;
}
return (is_logout);
}
Code Block 1 Authentication Configuration Variables
/********************************************************************************************************************************************************************************************************************GLOBAL VARIABLES*******************************************************************************************************************************************************************************************************************/
HTTPs_AUTHORIZATION_CFG HTTPs_AppGlobal_AuthInst_Cfg = { AppGlobal_Auth_GetRequiredRightsHook};
HTTPs_AUTH_CFG HTTPs_AuthAppCfg = { AppGlobal_Auth_ParseLoginHook, AppGlobal_Auth_ParseLogoutHook};
HTTPs_CTRL_LAYER_AUTH_INST AppGlobal_AuthInst = { &HTTPsAuth_CookieHooksCfg, &AppGlobal_AuthInst_Cfg};
HTTPs_CTRL_LAYER_APP_INST AppGlobal_AppInst_AuthUnprotected = { &HTTPsAuth_AppUnprotectedCookieHooksCfg, &AppGlobal_AppInst_AuthCfg};
HTTPs_CTRL_LAYER_APP_INST AppGlobal_AppInst_AuthProtected = { &HTTPsAuth_AppProtectedCookieHooksCfg, &AppGlobal_AppInst_AuthCfg };
HTTP Server REST module#
Introduction#
The REST Framework is built to be either used on top of the Control layer or the server core itself. It remaps the HTTP Server hooks or the applicative Control Layer hooks on a single hook per HTTP request method. This single method is called an HTTPs_REST_HOOK.
The REST Framework is designed to ease the production of simple web service applications. HTTP requests are made to perform actions on web resources. Inside your REST framework, those resources are mapped to HTTPs_REST_RESOURCE objects.
REST Resource#
A resource is associated with a specific path. REST Resources are accessible through path pattern matching and specifies the method supported and the headers needed. Here's the structure defining them:
Listing - REST Resource Structure#
typedef struct https_rest_resource {
const CPU_CHAR *PatternPtr; /* Access path to the resource ending with an EOF char. */
const HTTP_HDR_FIELD *HTTP_Hdrs; /* List of HTTP headers to keep. */
const CPU_SIZE_T HTTP_HdrsNbr; /* Number of HTTP headers in the list. */
const HTTPs_REST_METHOD_HOOKS MethodHooks; /* Hooks Configuration for the resource. */
} HTTPs_REST_RESOURCE;
Hooks Configuration#
Each REST resource has its own set of hook functions. Like mentioned before, there is one hook per HTTP method, but the hook pointer can be set to DEF_NULL in the configuration if not needed for the given resource.
Listing - REST Hooks Configuration Structure#
typedef struct https_rest_method_hooks {
HTTPs_REST_HOOK_FNCT Delete;
HTTPs_REST_HOOK_FNCT Get;
HTTPs_REST_HOOK_FNCT Head;
HTTPs_REST_HOOK_FNCT Post;
HTTPs_REST_HOOK_FNCT Put;
} HTTPs_REST_METHOD_HOOKS;
Below is the prototype for REST hook functions:
Listing - Definition of HTTPs_REST_HOOK_FNCT#
typedef HTTPs_REST_HOOK_STATE (*HTTPs_REST_HOOK_FNCT) (const HTTPs_REST_RESOURCE *p_resource,
const HTTPs_REST_MATCHED_URI *p_uri,
const HTTPs_REST_STATE state,
void **p_data,
const HTTPs_INSTANCE *p_instance,
HTTPs_CONN *p_conn,
void *p_buf,
const CPU_SIZE_T buf_size,
CPU_SIZE_T *p_buf_size_used);
Each hook is map on multiple hooks of the server core or Control Layer, therefore the same REST hook will be called many times during an HTTP transaction processing. To differentiate at which moment the REST hook is being called, a state variable HTTPs_REST_STATE is passed to the hook function. The table below presents a mapping of the HTTPS_REST_STATE with the corresponding HTTP server hooks.
REST STATE | Hook Function in REST Module | HTTP Server Hook | Control Layer Application Hook |
---|---|---|---|
HTTPs_REST_STATE_INIT | HTTPsREST_Authenticate() | (HTTPs_HOOK_CFG *)->OnReqHook() | (HTTPs_CTRL_LAYER_APP_HOOKS *)->OnReq() |
HTTPs_REST_STATE_RX | HTTPsREST_RxBody()HTTPsREST_ReqRdySignal() | (HTTPs_HOOK_CFG *)->OnReqBodyRxHook()(HTTPs_HOOK_CFG *)->OnReqRdySignalHook() with argument buf_size == 0 | (HTTPs_CTRL_LAYER_APP_HOOKS *)->OnReqBodyRx()(HTTPs_CTRL_LAYER_APP_HOOKS *)->OnReqSignal() |
HTTPs_REST_STATE_TX | HTTPsREST_GetChunk() | (HTTPs_HOOK_CFG *)->OnRespChunkHook() | (HTTPs_CTRL_LAYER_APP_HOOKS *)->OnRespChunk() |
HTTPs_REST_STATE_CLOSE | HTTPsREST_OnTransComplete()HTTPsREST_OnConnClosed() | (HTTPs_HOOK_CFG *)->OnTransCompleteHook()(HTTPs_HOOK_CFG *)->OnConnCloseHook() | (HTTPs_CTRL_LAYER_APP_HOOKS *)->OnTransComplete()(HTTPs_CTRL_LAYER_APP_HOOKS *)->OnConnClose() |
URI Pattern Matching#
The URI pattern matching of this framework is quite primitive and shines by its simplicity. The URI is divided into two sections: the separator and the path component. This leads to the following rules:
The pattern string must start with a separator.
The pattern string must end with a '\0'
A wild card can only be used between a separator and another separator or at the end of the pattern string.
A wild card will not match a separator char unless the wild card is the last component of the pattern string.
URI Path Separator#
The separator within the pattern string is exactly the same that must be found according to rfc3986 : '/'. This character cannot be escaped and can't be used in any other context.
URI Path Component#
A URI path component is the element between two path separator or between a path separator and the end of the pattern string. This element can either be a wild card or text.
Wild Cards#
The wild card begins with a { and ends with a }. A wild card cannot contain another wild card. The element between the curly brackets is used as the wild card token key.
URI Pattern and Match Examples#
Publish REST Resources#
Once a resource has been created, in order to make a resource accessible through the REST Framework, two steps must be followed. The first one is to call the HTTPsREST_Publish() function which will add the resource to the specified list. Then that list of resources is used in the configuration of the HTTP server.
This function can only be called after the HTTP server initialization and before the HTTP server start. Also, the HTTPsREST_Init() function must be bound to the HTTP server or to the Control layer prior the initialization. Otherwise, the REST memory pools won't be initialized and the resource lists cannot be created. |
---|
REST Configuration#
No matter which layer REST is bound to, the HTTP Server core or the Control Layer, you need to provide a HTTPs_REST_CFG structure. That structure is used to configure the REST framework behavior for that specific instance.
Listing - REST Configuration Structure#
typedef struct https_rest_cfg {
const CPU_INT32U ListID;
} HTTPs_REST_CFG;
Listing - Server Instance Configuration Example for REST Application#
/*
*********************************************************************************************************
* REST HOOKS CONFIGURATION
*********************************************************************************************************
*/
const HTTPs_REST_CFG HTTPs_REST_Cfg = { 0 }; /* 0 is the list ID number. The same used in */
/* the resources publishing. */
const HTTPs_HOOK_CFG HTTPs_REST_HookCfg = {
HTTPsREST_Init,
HTTPsREST_RxHeader,
HTTPsREST_Authenticate,
HTTPsREST_RxBody,
HTTPsREST_ReqRdySignal,
DEF_NULL,
DEF_NULL,
DEF_NULL,
HTTPsREST_GetChunk,
HTTPsREST_OnTransComplete,
DEF_NULL,
DEF_NULL,
HTTPsREST_OnConnClosed
};
/*
*********************************************************************************************************
* HTTP SERVER INSTANCE CONFIGURATION
*********************************************************************************************************
*/
const HTTPs_CFG AppEx_HTTPsInstanceCfg = {
...
/*
*---------------------------------------------------------------------------------
* HOOK CONFIGURATION
*---------------------------------------------------------------------------------
*/
&HTTPs_REST_HookCfg, /* .HooksPtr */
&HTTPs_REST_Cfg, /* .Hooks_CfgPtr */
...
};
The REST Hook Configuration variable HTTPs_REST_HookCfg and the variable HTTPs_REST_Cfg are given in a template file inside the REST module source code (http_server_rest_hook_cfg.c/h). You can use it has-is for your REST application or you can make your own if you don't need all the hooks to be defined. In the above example, the REST module is used directly on top of the HTTP server core, if you want to use it with the Control Layer, a template Control Layer hooks configuration for REST is also given inside the Control Layer add-on module source code (http_server_ctrl_layer_rest_cfg.c/h).
How to Use REST Module#
Create your REST resource(s) in your application.
Define the necessary hook functions for each HTTP method of each resource and set the hook configuration inside the REST resource declaration.
Set the REST configuration for the server instance configuration or the Control Layer configuration.
Use the API function HTTPsREST_Publish() between the HTTPs_InstanceInit() and HTTPs_InstanceStart() to publish all your REST resources inside the global resources list.
Example#
See the complete REST application available in the Example directory (see section HTTP Server Example Applications for more details).
HTTP Server Protocol Recognized Fields#
This section regroups lists of all the HTTP fields recognized by Micrium OS HTTP Server module.
HTTP Versions#
HTTP Version | Micrium Type |
---|---|
0.9 | HTTP_PROTOCOL_VER_0_9 |
1.0 | HTTP_PROTOCOL_VER_1_0 |
1.1 | HTTP_PROTOCOL_VER_1_1 |
HTTP Methods#
HTTP Method | Micrium Type |
---|---|
CONNECT | HTTP_METHOD_CONNECT |
DELETE | HTTP_METHOD_DELETE |
GET | HTTP_METHOD_GET |
HEAD | HTTP_METHOD_HEAD |
OPTIONS | HTTP_METHOD_OPTIONS |
POST | HTTP_METHOD_POST |
PUT | HTTP_METHOD_PUT |
TRACE | HTTP_METHOD_TRACE |
Those are the methods recognized by the HTTP Server and Client stacks. It doesn't mean that all those methods are supported. |
---|
HTTP Header Fields#
Header Field Type | Micrium Type |
---|---|
Content-Type | HTTP_HDR_FIELD_CONTENT_TYPE |
Content-Length | HTTP_HDR_FIELD_CONTENT_LEN |
Content-Disposition | HTTP_HDR_FILED_CONTENT_DISPOSITION |
Host | HTTP_HDR_FIELD_HOST |
Location | HTTP_HDR_FIELD_LOCATION |
Connection | HTTP_HDR_FIELD_CONN |
Transfer-Encoding | HTTP_HDR_FIELD_TRANSFER_ENCODING |
Accept | HTTP_HDR_FIELD_ACCEPT |
Accept-Charset | HTTP_HDR_FIELD_ACCEPT_CHARSET |
Accept-Encoding | HTTP_HDR_FIELD_ACCEPT_ENCODING |
Accept-Language | HTTP_HDR_FIELD_ACCEPT_LANGUAGE |
Accept-Ranges | HTTP_HDR_FIELD_ACCEPT_RANGES |
Age | HTTP_HDR_FIELD_AGE |
Allow | HTTP_HDR_FIELD_ALLOW |
Authorization | HTTP_HDR_FIELD_AUTHORIZATION |
Content-Encoding | HTTP_HDR_FIELD_CONTENT_ENCODING |
Content-Language | HTTP_HDR_FIELD_CONTENT_LANGUAGE |
Content-Location | HTTP_HDR_FIELD_CONTENT_LOCATION |
Content-MD5 | HTTP_HDR_FIELD_CONTENT_MD5 |
Content-Range | HTTP_HDR_FIELD_CONTENT_RANGE |
Cookie | HTTP_HDR_FIELD_COOKIE |
Cookie2 | HTTP_HDR_FIELD_COOKIE2 |
Date | HTTP_HDR_FIELD_DATE |
ETag | HTTP_HDR_FEILD_ETAG |
Expect | HTTP_HDR_FIELD_EXPECT |
Expires | HTTP_HDR_FIELD_EXPIRES |
From | HTTP_HDR_FIELD_FROM |
If-Modified-Since | HTTP_HDR_FIELD_IF_MODIFIED_SINCE |
If-Match | HTTP_HDR_FIELD_IF_MATCH |
If-None-Match | HTTP_HDR_FIELD_IF_NONE_MATCH |
If-Range | HTTP_HDR_FIELD_IF_RANGE |
If-Unmodified-Since | HTTP_HDR_FIELD_IF_UNMODIFIED_SINCE |
Last-Modified | HTTP_HDR_FIELD_LAST_MODIFIED |
Range | HTTP_HDR_FIELD_RANGE |
Referrer | HTTP_HDR_FIELD_REFERER |
Retry-After | HTTP_HDR_FIELD_RETRY_AFTER |
Server | HTTP_HDR_FIELD_SERVER |
Set-Cookie | HTTP_HDR_FIELD_SET_COOKIE |
Set-Cookie2 | HTTP_HDR_FIELD_SET_COOKIE2 |
TE | HTTP_HDR_FIELD_TE |
Trailer | HTTP_HDR_FIELD_TRAILER |
Upgrade | HTTP_HDR_FIELD_UPGRATE |
User-Agent | HTTP_HDR_FIELD_USER_AGENT |
Vary | HTTP_HDR_FIELD_VARY |
Via | HTTP_HDR_FIELD_VIA |
Warning | HTTP_HDR_FIELD_WARNING |
WWW-Authenticate | HTTP_HDR_FIELD_WWW_AUTHENTICATE |
If a header is missing for your application, contact your sales representative so that it can be included in subsequent release of Micrium OS. |
---|
HTTP Content Types#
MIME Content Type | File Extension | Micrium Type |
---|---|---|
text/html | .html | HTTP_CONTENT_TYPE_HTML |
application/octet-stream | .bin | HTTP_CONTENT_TYPE_OCTET_STREAM |
application/pdf | HTTP_CONTENT_TYPE_PDF | |
application/zip | .zip | HTTP_CONTENT_TYPE_ZIP |
image/gif | .gif | HTTP_CONTENT_TYPE_GIF |
image/jpeg | .jpeg, .jpg | HTTP_CONTENT_TYPE_JPEG |
image/png | .png | HTTP_CONTENT_TYPE_PNG |
application/javascript | .js | HTTP_CONTENT_TYPE_JS |
text/plain | .txt | HTTP_CONTENT_TYPE_PLAIN |
text/css | .css | HTTP_CONTENT_TYPE_CSS |
application/json | .json | HTTP_CONTENT_TYPE_JSON |
application/x-www-form-urlencoded | - | HTTP_CONTENT_TYPE_APP_FORM |
multipart/form-data | - | HTTP_CONTENT_TYPE_MULTIPART_FORM |
If a Content Type is missing for your application, contact your sales representative so that it can be included in subsequent release of Micrium OS. |
---|
HTTP Status Codes#
HTTP Status Code | Micrium Type |
---|---|
200 | HTTP_STATUS_OK |
201 | HTTP_STATUS_CREATED |
202 | HTTP_STATUS_ACCEPTED |
204 | HTTP_STATUS_NO_CONTENT |
205 | HTTP_STATUS_RESET_CONTENT |
301 | HTTP_STATUS_MOVED_PERMANENTLY |
302 | HTTP_STATUS_FOUND |
303 | HTTP_STATUS_SEE_OTHER |
304 | HTTP_STATUS_NOT_MODIFIED |
305 | HTTP_STATUS_USE_PROXY |
307 | HTTP_STATUS_TEMPORARY_REDIRECT |
400 | HTTP_STATUS_BAD_REQUEST |
401 | HTTP_STATUS_UNAUTHORIZED |
403 | HTTP_STATUS_FORBIDDEN |
404 | HTTP_STATUS_NOT_FOUND |
405 | HTTP_STATUS_METHOD_NOT_ALLOWED |
406 | HTTP_STATUS_NOT_ACCEPTABLE |
408 | HTTP_STATUS_REQUEST_TIMEOUT |
409 | HTTP_STATUS_CONFLICT |
410 | HTTP_STATUS_GONE |
411 | HTTP_STATUS_LENGTH_REQUIRED |
412 | HTTP_STATUS_PRECONDITION_FAILED |
413 | HTTP_STATUS_REQUEST_ENTITY_TOO_LARGE |
414 | HTTP_STATUS_REQUEST_URI_TOO_LONG |
415 | HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE |
416 | HTTP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE |
417 | HTTP_STATUS_EXPECTATION_FAILED |
500 | HTTP_STATUS_INTERNAL_SERVER_ERR |
501 | HTTP_STATUS_NOT_IMPLEMENTED |
503 | HTTP_STATUS_SERVICE_UNAVAILABLE |
505 | HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED |
If a Status Code is missing for your application, contact your sales representative so that it can be included in subsequent release of Micrium OS. |
---|
MQTT Client Module#
The Micrium OS MQTT Client allows your application to access MQTT servers and perform actions on resources stored on a server.
In an embedded environment, an MQTT client is used to publish values such as sensor data to a topic, and receive messages by subscribing to topics.
MQTT Client Overview#
The MQTT Client module allows your application to access MQTT brokers (also know as MQTT servers). Your application can publish messages and subscribe to topics of interest so that it can receive messages from other MQTT clients.
The MQTT Client module has been designed to have a very small memory footprint and be simple to use. It provides an API that is similar to other Micrium products, allowing you to start developing quickly.
The MQTT-client supports:
Multiple messages on same or different topics at the same time
Multiple connections to multiple servers
Every type of messages defined by the MQTT specifications V3.1 and V3.1.1, including the three levels of QoS for PUBLISH messages
See the section MQTT-client Message Types Supported for additional details on each feature.
Memory Usage#
MQTT client applications can have dramatically different memory requirements. For example, some applications will require a connection to only one server, while others may require more; some applications will prefer to allocate objects on their own stack, while others will want to use a memory pool on the heap. So to meet all of these different requirements, the MQTT client does not have its own memory module.
As a result, all the objects required by the MQTT client must be passed by the application. This includes a single MQTTc_MSG object that will be used to receive any incoming PUBLISH message from the server. For any message the application wishes to send to the server, an MQTTc_MSG object must also be provided. Each MQTTc_MSG object must have its own buffer, with a size varying from a few bytes for very simple messages to a few of hundred bytes for complex messages.
It is important that every object passed by the application to the MQTT-Client stay valid for the duration of the MQTT message (until the callback is called) or until the connection is closed for the MQTTc Connection Object using that message. |
---|
Internal Task#
To support multiple simultaneous connections, the MQTT Client module has a dedicated internal task. This task also allows the queuing of multiple messages on a given connection.
Auto Select Remote IP address#
When the DNS Client is present, the MQTT-Client can accept a hostname string to connect to the remote server. IP address resolution will be performed by a DNS server. If the DNS server sends back IPv4 and IPv6 addresses, the first attempt will be to use the IPv6 address to connect to the remote MQTT server. If this connection fails the IPv4 address will be used instead.
When the DNS Client is not present, you must pass an IPv4 or IPv6 remote address in string form to the MQTT-Client.
With its compile-time configuration, MQTT's code footprint can be adjusted to fit your application's requirements by enabling/disabling features.
MQTT Client Example Applications#
This section describes the examples application provided for the MQTT Client module of Micrium OS.
MQTT Client Initialization Example#
Description#
This is a generic example that shows how to initialize the MQTT client module. It accomplishes the following tasks:
Change default task's stacks size, if specified by the example configuration
Initialize the MQTTClient module
Change default the task's priority, if specified by the example configuration
Configuration#
Mandatory#
The following #define must be added in ex_description.h to allow other examples to initialize the HTTP Server module correctly:
#define | Description |
---|---|
EX_MQTT_CLIENT_INIT_AVAIL | Lets the upper example layer know that the Network Initialization example is present and must be called by other examples. |
Location#
/examples/net/mqtt/ex_mqtt_client_init.c
/examples/net/mqtt/ex_mqtt_client.h
API#
API | Description |
---|---|
Ex_MQTT_Client_Init() | Initialize the MQTT Client stack for the example application. |
Notes#
None.
MQTT Client Connect Example#
Description#
This is a generic example for the MQTT Client module. It shows how to connect to a broker.
Configuration#
Optional#
The following #define can be added to ex_description.h, as described in Example Applications section, to change default configuration value used by the example:
#define | Default value | Description |
---|---|---|
EX_MQTTc_BROKER_NAME | "mqtt.micrium.com" | Specify the broker hostname |
EX_MQTTc_USERNAME | "micrium" | Specify the username |
EX_MQTTc_PASSWORD | "micrium" | Specify the password |
EX_MQTTc_CLIENT_ID_NAME | "micrium-example-basic" | Specify another client ID |
EX_MQTTc_MSG_LEN_MAX | 128 | Specify the message maximum length |
EX_TRACE | printf(VA_ARGS) | Specify where to output information about the example |
Location#
/examples/net/mqtt/ex_mqtt_client_connect.c
/examples/net/mqtt/ex_mqtt_client.h
API#
API | Description |
---|---|
Ex_MQTT_Client_Connect() | Connect the client to the broker. |
Notes#
None.
MQTT Client Publish Example#
Description#
This is a generic example for the MQTT Client module. It accomplishes the following tasks:
Connect to a broker
Publish message on a topic
Configuration#
Optional#
The following #define can be added to ex_description.h, as described in Example Applications section, to change default configuration value used by the example:
#define | Default value | Description |
---|---|---|
EX_MQTTc_BROKER_NAME | Specify the broker hostname | |
EX_MQTTc_USERNAME | "micrium" | Specify the username |
EX_MQTTc_PASSWORD | "micrium" | Specify the password |
EX_MQTTc_CLIENT_ID_NAME | "micrium-example-publish" | Specify another client ID |
Location#
/examples/net/mqtt/ex_mqtt_client_publish.c
/examples/net/mqtt/ex_mqtt_client.h
API#
API | Description |
---|---|
Ex_MQTT_Client_Publish() | Open a connection and publish message from the callback |
Notes#
None.
MQTT Client Subscribe Example#
Description#
This is a generic example for the MQTT Client module. It accomplishes the following tasks:
Connect to a broker
Subscribe to a topic
Configuration#
Optional#
The following #define can be added to ex_description.h, as described in Example Applications section, to change default configuration value used by the example:
#define | Default value | Description |
---|---|---|
EX_MQTTc_BROKER_NAME | Specify the broker hostname | |
EX_MQTTc_USERNAME | "micrium" | Specify the username |
EX_MQTTc_PASSWORD | "micrium" | Specify the password |
EX_MQTTc_CLIENT_ID_NAME | "micrium-example-sub" | Specify another client ID |
Location#
/examples/net/mqtt/ex_mqtt_client_subscribe.c
/examples/net/mqtt/ex_mqtt_client.h
API#
API | Description |
---|---|
Ex_MQTT_Client_Subscribe() | Open a connection and subscribe to a topic. |
Notes#
None.
MQTT Client Echo Example#
Description#
This is a generic example for the MQTT Client module. It accomplishes the following tasks:
Connect to a broker
Subscribe to a topic
Publish on the subscribed topic
Configuration#
Optional#
The following #define can be added to ex_description.h, as described in Example Applications section, to change default configuration value used by the example:
#define | Default value | Description |
---|---|---|
EX_MQTTc_BROKER_NAME | Specify the broker hostname | |
EX_MQTTc_USERNAME | "micrium" | Specify the username |
EX_MQTTc_PASSWORD | "micrium" | Specify the password |
EX_MQTTc_CLIENT_ID_NAME | "micrium-example-echo" | Specify another client ID |
Location#
/examples/net/mqtt/ex_mqtt_client_echo.c
/examples/net/mqtt/ex_mqtt_client.h
API#
API | Description |
---|---|
Ex_MQTT_Client_Echo() | Open a connection and publish message from the callback and receive message using subscribe. |
Notes#
None.
MQTT Client Configuration#
This section describes the runtime configurations for the MQTT Client module.
Initialization#
To initialize the MQTT Client module, you call the function MQTTc_Init(). This function takes no configuration argument. Unless you override an optional configuration before calling the function MQTTc_Init(), the default configurations will be used.
Optional Configurations#
This section describes the optional configurations. If you do not set them in your application, the default configurations will apply.
The default values can be retrieved via the structure MQTTc_InitCfgDflt.
Note that these configurations must be set before you call the function MQTTc_Init(). |
---|
Table - MQTT Client Optional Configurations#
Configurations | Description | Type | Function to call | Default | Field from default configuration structure |
---|---|---|---|---|---|
Task's stack | The MQTT client module has a dedicated task. This configuration allows you to set the stack pointer and the stack size (in quantity of elements). | CPU_STK_SIZE void * | MQTTc_ConfigureTaskStk() | A stack of 512 elements allocated on Common 's memory segment. | .StkSizeElements.StkPtr |
Memory segment | The MQTT module allocates control data. You can specify the memory segment where such data should be located. | MEM_SEG * | MQTTc_ConfigureMemSeg() | .MemSegPtr | |
Quantity parameters | The MQTT client task use a message queue. You can overwrite the maximum element in the message pool. | MQTTc_QTY_CFG | MQTTc_ConfigureQty() | Unlimited queue size. | .QtyCfg |
Post-Init Configurations#
This section describes the configurations that can be set at any time during execution after you called the function MQTTc_Init().
These configurations are optional. If you do not set them in your application, the default configurations will apply.
Table - HTTP Client Post-init Configurations#
Configurations | Description | Type | Function to call | Default |
---|---|---|---|---|
Task priority | The MQTT client module creates a task. You can change the priority of this task at any time. | RTOS_TASK_PRIO | MQTTc_TaskPrioSet() | |
Task Delay | You can change the delay inside this task to allow a period of time for other tasks to run. | CPU_INT08U | MQTTc_TaskDlySet() | 1u |
Default Inactivity timeout | You can change the default inactivity assigned automatically to new connections. | CPU_INT16U | MQTTc_InactivityTimeoutDfltSet() | 1800u |
MQTT Client Programming Guide#
This section includes the following sub-topics:
Include Files#
To include MQTT functions in your application, include this file:
Include file | Description |
---|---|
rtos/net/include/mqtt_client.h | Functions used for MQTT API. |
Configuration#
Some parameters should be configured and/or optimized for your project requirements. See the section MQTT Client Configuration for further details.
API Reference#
Function name | Description |
---|---|
MQTTc_ConnClr() | Clears an MQTT client connection before its first usage. |
MQTTc_ConnSetParam() | Sets parameters related to the TCP and MQTT client connection. |
MQTTc_ConnOpen() | Opens a new MQTT client connection. |
MQTTc_ConnClose() | Request to close a MQTT client connection. |
MQTTc_MsgClr() | Clears the Message object members. |
MQTTc_MsgSetParam() | Sets parameters related to a given MQTT message. |
MQTTc_Connect() | Sends a 'Connect' message to the MQTT broker. |
MQTTc_Publish() | Sends a 'Publish' message to the MQTT broker. |
MQTTc_Subscribe() | Sends a 'Subscribe' message to the MQTT broker. |
MQTTc_SubscribeMult() | Sends a 'Subscribe' message containing multiple topics to MQTT broker. |
MQTTc_Unsubscribe() | Sends an 'Unsubscribe' message to the MQTT broker. |
MQTTc_UnsubscribeMult() | Sends an 'Unsubscribe' message for multiple topics to the MQTT broker. |
MQTTc_PingReq() | Sends a 'PingReq' message to the MQTT broker. |
MQTTc_Disconnect() | Sends a 'Disconnect' message to the MQTT broker. |
MQTT Client Objects#
This section describes the various structures that your application can use to create objects in order to use the MQTT Client. All MQTT Client objects must be allocated by the application and passed to the MQTT Client module.
All objects or strings passed to the MQTT Client module must stay valid and unmodified for the duration of the MQTT message (for message-oriented parameters and objects), or until the MQTT connection is closed (for Connection-oriented parameters and objects). |
---|
MQTT-Client Connection (MQTTc_CONN)#
This is the main structure used by MQTT Client module. It contains all parameters related to an MQTT connection (broker port number, broker address, broker host name, etc.) and also many internal parameters for the MQTT connection and MQTT message processing.
Each configurable parameter should be set up with the function MQTTc_ConnSetParam(). The list of available parameters for a connection can be viewed here .
Your application should never directly modify the members of an MQTT Client Connection object at any time.
Listing - MQTTc_CONN Structure#
struct mqttc_conn {
NET_SOCK_ID SockId; /* Connection's socket ID. */
CPU_INT08U SockSelFlags; /* Flags to identify which oper must be checked in Sel. */
CPU_CHAR *BrokerIP_Addr; /* MQTT broker's IP addr. */
CPU_CHAR *BrokerNamePtr; /* MQTT broker's name. */
CPU_INT16U BrokerPortNbr; /* MQTT broker's port nbr. */
CPU_INT16U InactivityTimeout_s; /* Inactivity timeout, in seconds. */
CPU_CHAR *ClientID_Str; /* Client ID str. */
CPU_CHAR *UsernameStr; /* Username str. */
CPU_CHAR *PasswordStr; /* Password str. */
CPU_INT16U KeepAliveTimerSec; /* Keep alive timer duration, in seconds. */
MQTTc_WILL_CFG *WillCfgPtr; /* Ptr to will cfg, if any. */
NET_APP_SOCK_SECURE_CFG *SecureCfgPtr; /* Ptr to secure will cfg, if any. */
/* -------------------- CALLBACKS --------------------- */
MQTTc_CMPL_CALLBACK OnCmpl; /* Generic, on cmpl callback. */
MQTTc_CMPL_CALLBACK OnConnectCmpl; /* On connect cmpl callback. */
MQTTc_CMPL_CALLBACK OnPublishCmpl; /* On publish cmpl callback. */
MQTTc_CMPL_CALLBACK OnSubscribeCmpl; /* On subscribe cmpl callback. */
MQTTc_CMPL_CALLBACK OnUnsubscribeCmpl; /* On unsubscribe cmpl callback. */
MQTTc_CMPL_CALLBACK OnPingReqCmpl; /* On ping req cmpl callback. */
MQTTc_CMPL_CALLBACK OnDisconnectCmpl; /* On disconnect cmpl callback. */
MQTTc_PUBLISH_RX_CALLBACK OnPublishRx; /* On publish rx'd cmpl callback. */
void *ArgPtr; /* Ptr to arg that will be provided to callbacks. */
CPU_INT32U TimeoutMs; /* Timeout for 'Open' operation, in milliseconds. */
/* ----------------- NEXT MSG VALUES ------------------ */
CPU_INT08U NextMsgHeader; /* Header of next msg to parse. */
CPU_INT32U NextMsgRxLen; /* Rx len of next msg. */
MQTTc_MSG_TYPE NextMsgType; /* Next msg's type. */
CPU_INT32U NextMsgLen; /* Len remaining to RX for next msg. */
CPU_BOOLEAN NextMsgLenIsCmpl; /* Flag indicating if next msg's len value is rx'd. */
CPU_INT16U NextMsgMsgID; /* ID of next msg, if any. */
CPU_BOOLEAN NextMsgMsgID_IsCmpl; /* Flag indicating if next msg's ID has been rx'd. */
MQTTc_MSG *NextMsgPtr; /* Ptr to next msg, if known. */
MQTTc_MSG *PublishRxMsgPtr; /* Ptr to msg that is used to RX publish from server. */
MQTTc_MSG *TxMsgHeadPtr; /* Ptr to head of msg needing to TX or waiting reply. */
CPU_INT32U NextTxMsgTxLen; /* Len of already xfer'd data. */
MQTTc_CONN *NextPtr; /* Ptr to next conn. */
};
MQTT Client Message (MQTTc_MSG)#
This structure contains parameters and flags related to the configuration of an MQTT message.
Each configurable parameter should be set up with the function MQTTc_MsgSetParam(). The list of available parameters for a connection can be viewed here .
Your application should never directly modify the members of an MQTT-Client Message object at any time.
Listing - MQTTc_MSG Structure#
struct mqttc_msg {
MQTTc_CONN *ConnPtr; /* Ptr to MQTTc_CONN associated. */
MQTTc_MSG_TYPE Type; /* Msg's type. */
MQTTc_MSG_STATE State; /* Msg's state. */
CPU_INT08U QoS; /* Msg's QoS. */
CPU_INT16U MsgID; /* Msg ID used by msg. */
CPU_INT08U *BufPtr; /* Ptr to RX/TX buf. */
CPU_INT32U BufLen; /* Avail buf len for msg. */
CPU_INT32U XferLen; /* Len of xfer. */
MQTTc_ERR Err; /* Err associated to processing of msg. */
MQTTc_MSG *NextPtr; /* Ptr to next msg. */
};
MQTT Client Connection Object Setup#
To configure the MQTT Client Connection object , the MQTT Client module provides the function MQTTc_ConnSetParam(). This function takes as arguments: the type of parameter, the parameter's value, and a pointer to the parameter. The following parameter types are available:
Generic Parameters#
Table - MQTTc Connection's Parameters#
Parameter Type | Description |
---|---|
MQTTc_PARAM_TYPE_BROKER_IP_ADDR | IP Address of the MQTT broker.This field is ignored if broker name is set. |
MQTTc_PARAM_TYPE_BROKER_NAME | Name of the MQTT broker.This method will work only if a DNS server is available**This field is ignored if the broker IP address is set. |
MQTTc_PARAM_TYPE_BROKER_PORT_NBR | Sets a specific port for the MQTT broker.By default, the port is set to 1883. |
MQTTc_PARAM_TYPE_INACTIVITY_TIMEOUT_S | Sets the inactivity timeout of the connectionThis value represents the time of inactivity allowed on a connection before it is automatically closed. |
MQTTc_PARAM_TYPE_CLIENT_ID_STR | Connection's Client ID. This ID should be unique among devices connected to the broker. |
MQTTc_PARAM_TYPE_USERNAME_STR | Connection's username string.This field is optional. |
MQTTc_PARAM_TYPE_PASSWORD_STR | Connection's password string.This field is optional. |
MQTTc_PARAM_TYPE_KEEP_ALIVE_TMR_SEC | Connection's keep alive, in seconds.This value represents the maximum allowed time between messages sent by the device to the broker.**If no message is sent for more than this time, the broker will close the connection. |
MQTTc_PARAM_TYPE_WILL_CFG_PTR | Pointer to last will and testament configuration.This field is optional. |
MQTTc_PARAM_TYPE_SECURE_CFG_PTR | Pointer to secure configuration.This field is optional. |
MQTTc_PARAM_TYPE_TIMEOUT_MS | Connection's timeout for socket 'Open', in milliseconds. |
MQTTc_PARAM_TYPE_PUBLISH_RX_MSG_PTR | Pointer to MQTT-client message object that will be used to receive PUBLISH messages from the broker.This parameter is *mandatory**.* |
Callback options#
Table - MQTTc Connection's Callbacks#
MQTTc_PARAM_TYPE_CALLBACK_ON_COMPL | Sets the generic callback function to notify the application whenever an event occurs. This callback is called before every other callback and may be used in place of all the other ones. |
MQTTc_PARAM_TYPE_CALLBACK_ON_CONNECT_CMPL | Sets the callback function to notify the application when a CONNECT message with the MQTT broker is completed.This parameter is optional. |
MQTTc_PARAM_TYPE_CALLBACK_ON_PUBLISH_CMPL | Sets the callback function to notify the application when a PUBLISH message with the MQTT broker is completed.This parameter is optional. |
MQTTc_PARAM_TYPE_CALLBACK_ON_SUBSCRIBE_CMPL | Sets the callback function to notify the application when a SUBSCRIBE message with the MQTT broker is completed.This parameter is optional. |
MQTTc_PARAM_TYPE_CALLBACK_ON_UNSUBSCRIBE_CMPL | Sets the callback function to notify the application when an UNSUBSCRIBE message with the MQTT broker is completed.This parameter is optional. |
MQTTc_PARAM_TYPE_CALLBACK_ON_PINGREQ_CMPL | Sets the callback function to notify the application when a PINGREQ message with the MQTT broker is completed.This parameter is optional. |
MQTTc_PARAM_TYPE_CALLBACK_ON_DISCONNECT_CMPL | Sets the callback function to notify the application when a DISCONNECT message with the MQTT broker is completed.This parameter is optional. |
MQTTc_PARAM_TYPE_CALLBACK_ON_ERR_CALLBACK | Sets the callback function to notify the application when an error with the socket connection occurs.A connection can be closed by the MQTT broker, by the client when an unexpected error occurred. To be able to re-open the socket connection and re-connect the client, this callback should be provided. This parameter is optional. |
MQTTc_PARAM_TYPE_CALLBACK_ON_PUBLISH_RX | Sets the callback function to notify the application when a PUBLISH message is received from the broker.This parameter is *mandatory**.* |
MQTTc_PARAM_TYPE_CALLBACK_ARG_PTR | Sets the argument that will be passed to every callback function.This parameter is optional. |
Example#
Listing - MQTTc Connection Configuration Example#
CPU_BOOLEAN App_MQTTc_ConnPrepare (MQTTc_CONN *p_conn)
{
RTOS_ERR err;
/* ---------- INIT NEW CONNECTION --------- */
MQTTc_ConnClr(p_conn, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
/* Set conn parameters. */
MQTTc_ConnSetParam( &AppMQTTc_Conn,
MQTTc_PARAM_TYPE_BROKER_NAME,
(void *)APP_MQTTc_BROKER_NAME,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
MQTTc_ConnSetParam( &AppMQTTc_Conn,
MQTTc_PARAM_TYPE_CLIENT_ID_STR,
(void *)APP_MQTTc_CLIENT_ID_NAME,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
MQTTc_ConnSetParam( &AppMQTTc_Conn,
MQTTc_PARAM_TYPE_USERNAME_STR,
(void *)APP_MQTTc_USERNAME,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
MQTTc_ConnSetParam( &AppMQTTc_Conn,
MQTTc_PARAM_TYPE_PASSWORD_STR,
(void *)APP_MQTTc_PASSWORD,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
MQTTc_ConnSetParam( &AppMQTTc_Conn,
MQTTc_PARAM_TYPE_KEEP_ALIVE_TMR_SEC,
(void *)1000u,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
MQTTc_ConnSetParam( &AppMQTTc_Conn,
MQTTc_PARAM_TYPE_CALLBACK_ON_COMPL,
(void *)AppMQTTc_OnCmplCallbackFnct,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
MQTTc_ConnSetParam( &AppMQTTc_Conn,
MQTTc_PARAM_TYPE_CALLBACK_ON_CONNECT_CMPL,
(void *)AppMQTTc_OnConnectCmplCallbackFnct,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
MQTTc_ConnSetParam( &AppMQTTc_Conn,
MQTTc_PARAM_TYPE_CALLBACK_ON_PUBLISH_CMPL,
(void *)AppMQTTc_OnPublishCmplCallbackFnct,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
MQTTc_ConnSetParam( &AppMQTTc_Conn,
MQTTc_PARAM_TYPE_CALLBACK_ON_SUBSCRIBE_CMPL,
(void *)AppMQTTc_OnSubscribeCmplCallbackFnct,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
MQTTc_ConnSetParam( &AppMQTTc_Conn,
MQTTc_PARAM_TYPE_CALLBACK_ON_ERR_CALLBACK,
(void *)AppMQTTc_OnErrCallbackFnct,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
MQTTc_ConnSetParam( &AppMQTTc_Conn,
MQTTc_PARAM_TYPE_PUBLISH_RX_MSG_PTR,
(void *)&AppMQTTc_MsgPublishRx,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
MQTTc_ConnSetParam( &AppMQTTc_Conn,
MQTTc_PARAM_TYPE_CALLBACK_ON_PUBLISH_RX,
(void *)AppMQTTc_OnPublishRxCallbackFnct,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
MQTTc_ConnSetParam( &AppMQTTc_Conn,
MQTTc_PARAM_TYPE_TIMEOUT_MS,
(void *)30000u,
&err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
return (DEF_OK);
}
MQTT Client Message Object Setup#
To set up an MQTT message, the MQTT Client provides the function MQTTc_MsgSetParam(). The function takes as arguments: the type of parameter, the pointer to the parameter, and the parameter's value. The following parameter types are available:
Table - MQTTc Message's Parameters#
Parameter Type | Description |
---|---|
MQTTc_PARAM_TYPE_MSG_BUF_PTR | Sets a pointer to the message. |
MQTTc_PARAM_TYPE_MSG_BUF_LEN | Sets the message's buffer length. |
Example#
Listing - MQTTc Message Configuration Example#
static MQTTc_MSG AppMQTTc_Msg;
static CPU_INT08U AppMQTTc_MsgBuf[APP_MQTTc_MSG_LEN_MAX];
CPU_BOOLEAN App_MQTTc_MsgPrepare (void)
{
RTOS_ERR err;
/* ------------ INIT NEW MESSAGE ------------ */
MQTTc_MsgClr(&AppMQTTc_Msg, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
MQTTc_MsgSetParam(&AppMQTTc_Msg, MQTTc_PARAM_TYPE_MSG_BUF_PTR, (void *)&AppMQTTc_MsgBuf[0u], &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
MQTTc_MsgSetParam(&AppMQTTc_Msg, MQTTc_PARAM_TYPE_MSG_BUF_LEN, (void *)APP_MQTTc_MSG_LEN_MAX, &err);
if (err.Code != RTOS_ERR_NONE) {
return (DEF_FAIL);
}
return (DEF_OK);
}
MQTT Client Callback Functions#
Callback functions are used by the MQTT Client module to notify your application when certain activities occur in the MQTT Client core.
Callbacks can be set up by using the MQTTc_ConnSetParam() function. The p_arg parameter that is passed in every callback can be set via MQTTc_ConnSetParam() by using MQTTc_PARAM_TYPE_CALLBACK_ARG_PTR as the type argument.
No blocking calls (delays, pending on an OS object, etc.) or long operations should ever be performed in any of these callbacks. These callbacks are executed from the MQTT Client internal task, and if this task is delayed or blocked, the entire MQTT Client module will be delayed/blocked too, preventing the reception or transmission of any message on any connection. |
---|
On Complete Callbacks#
The following callbacks are of type MQTTc_CMPL_CALLBACK. Even though they are optional, they are necessary for your application to know when a particular message has been completely sent, in order to re-use it for another message. The generic complete callback may be used to emulate all other callbacks in this category.
Table - MQTTc On Complete Callback Functions#
Trigger Event | Description | type argument for MQTTc_ConnSetParam() |
---|---|---|
Any message completed (in this section, not a received PUBLISH message) | Generic notification for any event. | MQTTc_PARAM_TYPE_CALLBACK_ON_COMPL |
CONNECT message completed | Notify that a CONNECT message has completed. | MQTTc_PARAM_TYPE_CALLBACK_ON_CONNECT_CMPL |
PUBLISH (to broker) message completed | Notify that a PUBLISH message has completed. | MQTTc_PARAM_TYPE_CALLBACK_ON_PUBLISH_CMPL |
SUBSCRIBE message completed | Notify that a SUBSCRIBE message has completed. | MQTTc_PARAM_TYPE_CALLBACK_ON_SUBSCRIBE_CMPL |
UNSUBSCRIBE message completed | Notify that an UNSUBSCRIBE message has completed. | MQTTc_PARAM_TYPE_CALLBACK_ON_UNSUBSCRIBE_CMPL |
PINGREQ message completed | Notify that a PINGREQ message has completed. | MQTTc_PARAM_TYPE_CALLBACK_ON_PINGREQ_CMPL |
DISCONNECT message completed | Notify that a DISCONNECT message has completed. | MQTTc_PARAM_TYPE_CALLBACK_ON_DISCONNECT_CMPL |
On Error Callback#
This callback is of type MQTTc_ERR_CALLBACK. Even though it is optional, we recommend that your application make use of it to know if an error occurs.
Table - MQTTc On Error Callback Function#
Trigger Event | Description | type argument for MQTTc_ConnSetParam() |
---|---|---|
Whenever an error occurs on the connection and is not related to a particular message | Notify that an error occurred on the connection. | MQTTc_PARAM_TYPE_CALLBACK_ON_ERR_CALLBACK |
On PUBLISH Message Received Callback#
This callback is of type MQTTc_PUBLISH_RX_CALLBACK. This callback is required only if the application expects to receive data from the broker. If not, it will never be called.
Table - MQTTc On PUBLISH received Callback Function#
Trigger Event | Description | type argument for MQTTc_ConnSetParam() |
---|---|---|
A PUBLISH message has been completely received | Notify that a PUBLISH message has completed to be received. | MQTTc_PARAM_TYPE_CALLBACK_ON_PUBLISH_RX |
MQTT Client - On Complete Callback Type#
This callback function type is used by any callback that receives a notification when a message exchange with the broker has been completed, successfully or not. The parameters passed are the same in every callback and are detailed below.
Prototype#
typedef void (*MQTTc_CMPL_CALLBACK) (MQTTc_CONN *p_conn,
MQTTc_MSG *p_msg,
void *p_arg,
RTOS_ERR err);
Arguments#
p_conn
Pointer to the current MQTTc Connection Object.
p_msg
Pointer to the MQTTc Message Object used to send the message to the broker.
In the generic complete callback, you can use p_msg->Type to find out the type of message that just completed. The other fields of p_msg may not be relied upon.
p_arg
Pointer to the argument specified by your application via MQTTc_ConnSetParam() with the MQTTc_PARAM_TYPE_CALLBACK_ARG_PTR type.
err
Error code for this operation.
Return Values#
None.
Notes / Warnings#
None.
Example Template#
Listing - CONNECT Complete Callback Example#
static void AppMQTTc_OnConnectCmplCallbackFnct (MQTTc_CONN *p_conn,
MQTTc_MSG *p_msg,
void *p_arg,
RTOS_ERR err)
{
RTOS_ERR err_mqttc;
(void)&p_arg;
if (err.Code != RTOS_ERR_NONE) {
printf("ConnectCmpl callback called with err (%i). NOT sending PUBLISH message.\n\r", err);
} else {
printf("ConnectCmpl callback called. Sending PUBLISH message.\n\r");
MQTTc_Publish(p_conn,
p_msg,
APP_MQTTc_DOMAIN_PUBLISH,
APP_MQTTc_PUBLISH_TEST_QoS,
DEF_YES,
APP_MQTTc_PUBLISH_TEST_MSG,
&err_mqttc);
if (err_mqttc.Code != RTOS_ERR_NONE) {
printf("!!! APP ERROR !!! Failed to Publish test string. Err: %i\n\r.", err_mqttc);
}
}
}
Listing - Generic Complete Callback Example#
static void AppMQTTc_OnCmplCallbackFnct (MQTTc_CONN *p_conn,
MQTTc_MSG *p_msg,
void *p_arg,
RTOS_ERR err)
{
(void)&p_conn;
(void)&p_arg;
if (err.Code != RTOS_ERR_NONE) {
printf("Operation completed with err (%i). ", err);
}
switch (p_msg-\>Type) {
case MQTTc_MSG_TYPE_CONNECT: /\* Gen callback called for event type: Connect Cmpl. \*/
printf("Gen callback called for event type: Connect Cmpl.\n\r");
break;
case MQTTc_MSG_TYPE_PUBLISH: /\* Gen callback called for event type: Publish Cmpl. \*/
printf("Gen callback called for event type: Publish Cmpl.\n\r");
break;
case MQTTc_MSG_TYPE_SUBSCRIBE: /\* Gen callback called for event type: Subscribe Cmpl. \*/
printf("Gen callback called for event type: Subscribe Cmpl.\n\r");
break;
case MQTTc_MSG_TYPE_UNSUBSCRIBE: /\* Gen callback called for event type: Unsubscribe Cmpl.\*/
printf("Gen callback called for event type: Unsubscribe Cmpl.\n\r");
break;
case MQTTc_MSG_TYPE_PINGREQ: /\* Gen callback called for event type: PingReq Cmpl. \*/
printf("Gen callback called for event type: PingReq Cmpl.\n\r");
break;
case MQTTc_MSG_TYPE_DISCONNECT: /\* Gen callback called for event type: Disconnect Cmpl. \*/
printf("Gen callback called for event type: Disconnect Cmpl.\n\r");
break;
default:
printf("Gen callback called for event type: default. !!! ERROR !!! %i\n\r", p_msg-\>Type);
break;
}
}
MQTT Client - On Error Callback Type#
This callback function type is used to notify your application that an error occurred within the stack that is not related to a particular message.
Prototype#
typedef void (*MQTTc_ERR_CALLBACK) (MQTTc_CONN *p_conn,
void *p_arg,
RTOS_ERR err);
Arguments#
p_conn
Pointer to the current MQTTc Connection Object.
p_arg
Pointer to the argument specified by your application via MQTTc_ConnSetParam() with the MQTTc_PARAM_TYPE_CALLBACK_ARG_PTR type.
err
Error code.
Return Values#
None.
Notes / Warnings#
After this callback is called, your application must re-call MQTTc_ConnOpen() , and MQTTc_Connect(), since both the TCP and MQTT connections will have been closed. We recommend that you do this outside the scope of the callback, to avoid slowing the whole MQTTc stack if it has other messages to process.
Example Template#
Listing - On Error Callback Example#
static void AppMQTTc_OnErrCallbackFnct (MQTTc_CONN *p_conn,
void *p_arg,
RTOS_ERR err)
{
(void)&p_conn;
(void)&p_arg;
printf("!!! APP ERROR !!! Err detected via OnErr callback. Err = %s.\n\r", err.CodeText);
}
MQTT Client - On PUBLISH Received Callback Type#
This callback function type is used to notify your application that a PUBLISH message has been received or that there has been an error when trying to receive it.
Prototype#
typedef void (*MQTTc_PUBLISH_RX_CALLBACK) ( MQTTc_CONN *p_conn,
const CPU_CHAR *topic_name_str,
CPU_INT32U topic_len,
const CPU_INT08U *p_message,
CPU_INT32U message_len,
void *p_arg,
RTOS_ERR err);
Arguments#
p_conn
Pointer to the current MQTTc Connection Object.
topic_name_str
Pointer to the start of the string containing the topic name. Note: For performance reasons, this string is not NULL-terminated.
topic_len
Length, in bytes, of the topic string.
p_message
Pointer to the start of the buffer containing the message.
message_len
Length, in bytes, of the message.
p_arg
Pointer to the argument specified by the application via MQTTc_ConnSetParam() with the MQTTc_PARAM_TYPE_CALLBACK_ARG_PTR type.
err
Error code for this operation.
Return Values#
None.
Notes / Warnings#
None.
Example Template#
Listing - On PUBLISH Received Callback Example(1) This example assumes that the message is string-based and NULL terminated#
static void AppMQTTc_OnPublishRxCallbackFnct ( MQTTc_CONN *p_conn,
const CPU_CHAR *topic_name_str,
CPU_INT32U topic_len,
const CPU_INT08U *p_message,
CPU_INT32U message_len,
void *p_arg,
RTOS_ERR err)
{
(void)&p_conn;
(void)&p_arg;
if (err.Code != RTOS_ERR_NONE) {
printf("!!! APP ERROR !!! Err detected when receiving a PUBLISH message (%s).\n\r", err.CodeText);
}
printf("Received PUBLISH message from server. Topic is %.*s.", topic_len, topic_name_str);
printf(" Message is %s.", (CPU_CHAR *)p_message); /* See Note #1. */
}
MQTT Client Message Types Supported#
MQTT Message Type | Associated Function | Associated Callback Type (set via MQTTc_ConnSetParam()) |
---|---|---|
CONNECTCONNACK | MQTTc_Connect() | MQTTc_PARAM_TYPE_CALLBACK_ON_CONNECT_CMPL |
PUBLISH (to server)PUBACKPUBRECPUBRELPUBCOMP | MQTTc_Publish() | MQTTc_PARAM_TYPE_CALLBACK_ON_PUBLISH_CMPL |
PUBLISH (from server)PUBACKPUBRECPUBRELPUBCOMP | None, waiting on server. | MQTTc_PARAM_TYPE_CALLBACK_ON_PUBLISH_RX |
SUBSCRIBESUBACK | MQTTc_Subscribe(),MQTTc_SubscribeMult() | MQTTc_PARAM_TYPE_CALLBACK_ON_SUBSCRIBE_CMPL |
UNSUBSCRIBEUNSUBACK | MQTTc_Unsubscribe(),MQTTc_UnsubscribeMult() | MQTTc_PARAM_TYPE_CALLBACK_ON_UNSUBSCRIBE_CMPL |
PINGREQPINGRESP | MQTTc_PingReq() | MQTTc_PARAM_TYPE_CALLBACK_ON_PINGREQ_CMPL |
DISCONNECT | MQTTc_Disconnect() | MQTTc_PARAM_TYPE_CALLBACK_ON_DISCONNECT_CMPL |
SNTP Client Module#
SNTP Client Overview#
The Simple Network Time Protocol (SNTP) is a protocol used to synchronized computer clock times in a computer network. SNTP uses Universal Time Coordinated (UTC) to synchronize computer clocks to the millisecond, and sometimes to a fraction of a millisecond. The SNTP Client module implements the following RFC:
ftp-ftp-rfc-editor-org-in-notes-rfc4330-txt
SNTP Client Example Applications#
This section describes the examples that are related to the Micrium OS SNTP Client module.
SNTP Client Initialization Example#
Description#
This is a generic example that shows how to initialize the SNTP client module.
Configuration#
Mandatory#
The following #define must be added in ex_description.h to allow other examples to initialize the SNTP Client module correctly:
#define | Description |
---|---|
EX_SNTP_CLIENT_INIT_AVAIL | Lets the upper example layer know that the SNTP Client Initialization example is present and must be called by other examples. |
Optional#
The following #define can be added to ex_description.h, as described in Example Applications section, to change default configuration value used by the example:
#define | Default value | Description |
---|---|---|
EX_TRACE | printf(VA_ARGS) | Specify the function used to output information |
Location#
/examples/net/sntp/ex_sntp_client.c
/examples/net/sntp/ex_sntp_client.h
API#
API | Description |
---|---|
Ex_SNTP_Client_Init() | Initialize the Micrium OS SNTP Client module for the example application. |
Notes#
None.
Basic SNTP Current Time Retrieve#
Description#
This is a simple example that will retrieve the current time from the following NTP server: 0.pool.ntp.org.
The example will then display the current time in the following format:
Day <day> of year <year>. Time: hh:mm:ss(UTC) |
---|
Location#
/examples/net/sntp/ex_sntp_client.c
/examples/net/sntp/ex_sntp_client.h
Configuration#
Optional#
The following #define can be added to ex_description.h, as described in Example Applications section, to change default configuration value used by the example:
#define | Default value | Description |
---|---|---|
EX_TRACE | printf(VA_ARGS) | Specify the function used to output information |
API#
API | Description |
---|---|
Ex_SNTP_Client_CurTimeDisplay() | Retrieves the current time from the NTP server and displays it |
Notes#
None.
SNTP Client Configuration#
Initialization#
Initializing the SNTP Client module is done by calling the function SNTPc_Init(). This function takes no configuration argument. Unless you override an optional configuration before calling the function SNTPc_Init(), the default configurations will be used.
Optional Configurations#
This section describes the configurations that are optional. If you do not set them in your application, the default configurations will apply.
You can retrieve the default values from the structure SNTPc_InitCfgDflt.
Note that these configurations must be set before you call the function SNTPc_Init(). |
---|
Table - SNTP Client Optional Configurations#
Configurations | Description | Type | Function to call | Default | Field from default configuration structure |
---|---|---|---|---|---|
Memory segment | This module allocates some control data. You can specify the memory segment from where such data should be allocated. | MEM_SEG* | SNTPc_ConfigureMemSeg() | .MemSegPtr |
Post-Init Configurations#
This section describes the configurations that can be set at any time during execution after you called the function SNTPc_Init().
These configurations are optional. If you do not set them in your application, the default configurations will apply.
Table - SNTP Client Post-init Configurations#
SNTP Client Programming Guide#
This section describes the basic steps required to initialize and use the Simple Network Time Protocol (SNTP) module.
Initializing the SNTP Client Module#
First step is to initialize the SNTP client module. This is done by calling the function SNTPc_Init(). Note that the Network module MUST be initialized before the SNTP Client module.
Listing - Example of call to SNTPc_Init() in the SNTP Client Programming Guide page gives an example of call to SNTPc_Init().
Listing - Example of call to SNTPc_Init()#
RTOS_ERR err;
SNTPc_Init(&err);
if (err.Code != RTOS_ERR_NONE) {
/* An error occurred. Error handling should be added here. */
}
Requesting Remote Time#
Once you successfully initialized the SNTP Client module, you can request the remote time This is done by calling the function SNTPc_ReqRemoteTime().
Listing - Example of call to SNTPc_ReqRemoteTime() in the SNTP Client Programming Guide page gives an example of call to SNTPc_ReqRemoteTime() using default arguments. In this example, the remote NTP server is 0.pool.ntp.org.
Listing - Example of call to SNTPc_ReqRemoteTime()#
RTOS_ERR err;
SNTP_PKT pkt;
SNTPc_ReqRemoteTime("0.pool.ntp.org",
&pkt,
&err);
if (err.Code != RTOS_ERR_NONE) {
/* An error occurred. Error handling should be added here. */
}
Retrieving Current Time#
Once you successfully requested the remote time, you can compute the current time. This is done by calling the function SNTPc_GetRemoteTime(). This function will take the pointer to the variable of type SNTP_PKT that was given to the function SNTPc_ReqRemoteTime() previously. Note that the returned time is UTC.
Listing - Example of call to SNTPc_GetRemoteTime() in the SNTP Client Programming Guide page gives an example of call to SNTPc_GetRemoteTime().
Listing - Example of call to SNTPc_GetRemoteTime()#
SNTP_TS ts;
RTOS_ERR err;
ts = SNTPc_GetRemoteTime(&pkt, &err);
if (err.Code != RTOS_ERR_NONE) {
/* An error occurred. Error handling should be added here. */
}
ts.Sec; /* Represents the quantity of seconds since Jan 1, 1900. */
ts.Frac; /* Represents the fractions of second. 32 bit precision. */
SMTP Client Module#
SMTP Client Overview#
SMTP (Simple Mail Transfer Protocol) is a protocol designed to transfer mail reliably and efficiently. When an SMTP client has a message to transmit, it establishes a two-way transmission channel to an SMTP server. The responsibility of an SMTP client is to transfer mail messages to a SMTP server, or report its failure to do so [RFC 2821].
Micrium OS SMTP module implement part of the following RFC:
ftp-ftp-rfc-editor-org-in-notes-rfc2821-txt
ftp-ftp-rfc-editor-org-in-notes-rfc2822-txt
ftp-ftp-rfc-editor-org-in-notes-rfc4616-txt
ftp-ftp-rfc-editor-org-in-notes-rfc4648-txt
ftp-ftp-rfc-editor-org-in-notes-rfc4954-txt
SMTP Client Example Applications#
This section describes the examples that are related to the Micrium OS SMTP Client module.
SMTP Client Initialization Example#
Description#
This is a generic example that shows how to initialize the SMTP client module.
Configuration#
Mandatory#
The following #define must be added in ex_description.h to allow other examples to initialize the SNTP Client module correctly:
#define | Description |
---|---|
EX_SMTP_CLIENT_INIT_AVAIL | Lets the upper example layer know that the SMTP Client Initialization example is present and must be called by other examples. |
Location#
/examples/net/smtp/ex_smtp_client.c
/examples/net/smtp/ex_smtp_client.h
API#
API | Description |
---|---|
Ex_SMTP_Client_Init() | Initialize the Micrium OS SMTP Client module for the example application. |
Notes#
None.
SMTP Client Send Email Example#
Description#
This is a simple example that sends an email.
Configuration#
Mandatory#
The following #define must be added in ex_description.h to allow other examples to initialize the SNTP Client module correctly:
#define | Description |
---|---|
EX_SMTPc_SERVER_ADDR | Specify the SMTP server address to use. One should be provided by your ISP or by your organization.Note that the default value is invalid ("smtp.isp.com "). |
EX_SMTPc_TO_ADDR | Specify the destination email address, i.e., your email address. Note that the default value is invalid ("test_to@gmail.com "). |
Optional#
The following #define can be added to ex_description.h, as described in Example Applications section, to change default configuration value used by the example:
#define | Default value | Description |
---|---|---|
EX_SMTPc_FROM_NAME | "From Name" | Specify the displayed name of the sender |
EX_SMTPc_FROM_ADDR | "test_from@gmail.com " | Specify the email address of the sender |
EX_SMTPc_USERNAME | DEF_NULL | Specify a username, if null no authentication is applied. |
EX_SMTPc_PW | DEF_NULL | Specify a password. |
EX_SMTPc_MSG_SUBJECT | "Example Title" | Specify the email subject |
EX_SMTPc_MSG_BODY | "Example email sent using Micrium OS" | Specify the email body |
EX_TRACE | printf(VA_ARGS) | Specify the function used to output information |
Location#
/examples/net/smtp/ex_smtp_client.c
/examples/net/smtp/ex_smtp_client.h
API#
API | Description |
---|---|
Ex_SMTP_Client_SendMail() | Send an email |
SMTP Client Configuration#
Initialization#
Initializing the SMTP Client module is done by calling the function SMTPc_Init(). This function takes no configuration argument. Unless you override an optional configuration before calling the function SMTPc_Init(), the default configurations will be used.
Optional Configurations#
This section describes the configurations that are optional. If you do not set them in your application, the default configurations will apply.
The default values can be retrieved via the structure SMTPc_InitCfgDflt.Note that these configurations must be set before you call the function SMTPc_Init().
Table - SMTP Client Optional Configurations#
Configurations | Description | Type | Function to call | Default | Field from default configuration structure |
---|---|---|---|---|---|
Memory segment | This module allocates some control data. You can specify the memory segment from where such data should be allocated. | MEM_SEG* | SMTPc_ConfigureMemSeg() | .MemSegPtr | |
Authentication encodes buffers | This module allocates buffers to encode the authentication data (user name and password). Two type of buffer are allocated; small buffers which will contain the username and the password and large buffers which will receive the encoded data. | CPU_INT16U | SMTPc_ConfigureAuthBufLen() | .AuthBufInputLen = 100.AuthBufOutputLen = 140 | .AuthBufInputLen.AuthBufOutputLen |
Post-Init Configurations#
This section describes the configurations that can be set at any time during execution after you called the function SMTPc_Init().
These configurations are optional. If you do not set them in your application, the default configurations will apply.
Table - SMTP Client Post-init Configurations#
SMTP Client Programming Guide#
This section describes the basic steps required to initialize and use the Simple Mail Transfer Protocol (SMTP) module.
Initializing the SMTP Client Module#
The first step is to initialize the SMTP client module. This is done by calling the function SMTPc_Init(). Note that the Network module MUST be initialized before the SMTP Client module.
Listing - Example of call to SNTPc_Init() in the SMTP Client Programming Guide page gives an example of a call to SMTPc_Init() .
Listing - Example of call to SNTPc_Init()#
RTOS_ERR err;
SMTPc_Init(&err);
if (err.Code != RTOS_ERR_NONE) {
/* An error occured. Error handling should be added here. */
}
Prepare Mail Message#
Once you have successfully initialized the SMTP Client module, you can prepare message to be sent using SMTP client module :
SMTPc_MsgAlloc()
SMTPc_MsgClr()
SMTPc_MsgFree()
SMTPc_MsgSetParam()
Listing - Example of how to prepare a mail message in the SMTP Client Programming Guide page gives an example of how to prepare a mail message:
Listing - Example of how to prepare a mail message#
RTOS_ERR err;
SMTPc_MSG *p_msg;
p_msg = (SMTPc_MSG *)SMTPc_MsgAlloc(&err);
APP_RTOS_ASSERT_CRITICAL(err.Code == RTOS_ERR_NONE, ;);
SMTPc_MsgSetParam(p_msg, SMTPc_FROM_ADDR, "test_from@mail.com", &err);
APP_RTOS_ASSERT_CRITICAL(err.Code == RTOS_ERR_NONE, ;);
SMTPc_MsgSetParam(p_msg, SMTPc_FROM_DISPL_NAME, "From Name", &err);
APP_RTOS_ASSERT_CRITICAL(err.Code == RTOS_ERR_NONE, ;);
SMTPc_MsgSetParam(p_msg, SMTPc_TO_ADDR, "test_to@mail.com", &err);
APP_RTOS_ASSERT_CRITICAL(err.Code == RTOS_ERR_NONE, ;);
SMTPc_MsgSetParam(p_msg, SMTPc_MSG_SUBJECT, "This is the mail title", &err);
APP_RTOS_ASSERT_CRITICAL(err.Code == RTOS_ERR_NONE, ;);
SMTPc_MsgSetParam(p_msg, SMTPc_MSG_BODY, "This is the mail message body", &err);
APP_RTOS_ASSERT_CRITICAL(err.Code == RTOS_ERR_NONE, ;);
// TODO send message
SMTPc_MsgFree(p_msg, &err);
APP_RTOS_ASSERT_CRITICAL(err.Code == RTOS_ERR_NONE, ;);
Send Mail#
Once you have configured you mail message, you can transfer the mail using a remote SMTP server. You can send email using a high-level SMTPc_SendMail() function if you just need to send one email as shown by Listing - Example of call to SMTPc_SendMail() in the SMTP Client Programming Guide page.
Listing - Example of call to SMTPc_SendMail()#
SMTPc_MSG *p_msg;
RTOS_ERR err;
p_msg = (SMTPc_MSG *)SMTPc_MsgAlloc(&err);
APP_RTOS_ASSERT_CRITICAL(err.Code == RTOS_ERR_NONE, ;);
SMTPc_MsgSetParam(p_msg, SMTPc_FROM_ADDR, EX_SMTPc_FROM_ADDR, &err);
APP_RTOS_ASSERT_CRITICAL(err.Code == RTOS_ERR_NONE, ;);
SMTPc_MsgSetParam(p_msg, SMTPc_FROM_DISPL_NAME, EX_SMTPc_FROM_NAME, &err);
APP_RTOS_ASSERT_CRITICAL(err.Code == RTOS_ERR_NONE, ;);
SMTPc_MsgSetParam(p_msg, SMTPc_TO_ADDR, EX_SMTPc_TO_ADDR, &err);
APP_RTOS_ASSERT_CRITICAL(err.Code == RTOS_ERR_NONE, ;);
SMTPc_MsgSetParam(p_msg, SMTPc_MSG_SUBJECT, EX_SMTPc_MSG_SUBJECT, &err);
APP_RTOS_ASSERT_CRITICAL(