Microvisor is in a pre-release phase and the information contained in this document is subject to change. Some features referenced below may not be fully available until Microvisor's General Availability (GA) release.
Microvisor system calls currently include the following functions to manage HTTP communications over the Internet.
The HTTP functions for managing requests and the responses they generate operate through Microvisor network channels. To learn how to establish network connections, and open channels through them, please see Microvisor network functions.
All of the functions described below return a 32-bit integer that is one of the values from the standard Microvisor enumeration MvStatus
. All possible error values for a given system call are provided with each function's description.
Success is always signaled by a return value of zero (MV_STATUS_OKAY
).
Issue an HTTP request via a channel
1extern enum MvStatus mvSendHttpRequest(MvChannelHandle handle,2const struct MvHttpRequest *request);
Parameter | Description |
---|---|
handle | The handle of the channel that will issue the request. This must be a channel of type MV_CHANNELTYPE_HTTP |
request | A pointer to non-secure memory in which network configuration data is stored by the application |
Error Value | Description |
---|---|
MV_STATUS_PARAMETERFAULT | request does not reference memory accessible to the application |
MV_STATUS_LATEFAULT | One or more of the pointers within request — see below — are illegal |
MV_STATUS_INVALIDHANDLE | handle does not reference a valid channel of type MV_CHANNELTYPE_HTTP |
MV_STATUS_INVALIDBUFFERSIZE | The request structure will not fit in the channel's send buffer |
MV_STATUS_TOOMANYELEMENTS | Too many headers (i.e., more than 32) are attached to request |
MV_STATUS_CHANNELCLOSED | The specified channel has already been closed |
MV_STATUS_REQUESTALREADYSENT | The request has already been sent, either successfully or not |
This call, if successful, may subsequently yield any of the following notifications.
Notification Event Type | Description |
---|---|
MV_EVENTTYPE_CHANNELDATAREADABLE | Issued to the host channel's notification center when data has been received through the channel. Call mvReadHttpResponseData() to the ultimate outcome of the request |
The application makes use of channels of type MV_CHANNELTYPE_HTTP
to issue HTTP requests to remote servers. The channel must be open for the request to be issued and of the correct type.
For each channel, only one request can be issued. If Microvisor returns MV_STATUS_PARAMETERFAULT
, MV_STATUS_INVALIDHANDLE
, MV_STATUS_INVALIDBUFFERSIZE
or MV_STATUS_CHANNELCLOSED
, then the request will not have been issued, and you can reconfigure the request and try again. Any other value indicates that the request has been sent, and any attempt to issue it again, or to use the channel for a fresh request, will result in MV_STATUS_REQUESTALREADYSENT
being returned. Instead, send any subsequent HTTP request through a new channel. You can re-use the channel definition structure and buffers if you wish. Be sure to close the channel used for a given HTTP request once you have received the response or a failure notification.
The type of HTTP request is specified as the scheme prefix of the target URL. Only HTTPS — i.e., https://
— is supported. If your URL is prefixed http://
, or some other scheme, the request will be rejected: the device will receive an MvHttpResponseData
record with its result
field equal to MV_HTTPRESULT_UNSUPPORTED_URI_SCHEME
. Please see mvReadHttpResponseData()
for details of the MvHttpResponseData
structure.
The call's request
parameter takes a pointer to a MvHttpRequest
structure:
1struct MvHttpRequest {2struct MvSizedString method;3struct MvSizedString url;4uint32_t num_headers;5const struct MvHttpHeader *headers;6struct MvSizedString body;7uint32_t timeout_ms;8};
This structure's properties are:
method
— A data structure comprising the request HTTP method, i.e., GET
, HEAD
, POST
, PUT
, DELETE
, PATCH
or OPTIONS
, as bytes and the number of bytes.url
— A data structure comprising the target URL as bytes and the number of bytes. Only https://
is supported as a prefix.num_headers
— The number of headers included in the headers
array.headers
— A pointer to an array of one or more MvHttpHeader
structures.body
— A data structure comprising the request body content as bytes and the number of bytes. Include an empty string if there is no body content.timeout_ms
— The request timeout in milliseconds. Microvisor supports timeouts from 5000ms to 10000ms.Each entry in the headers
array, if any, is a pointer to an MvHttpHeader
structure:
1struct MvHttpHeader {2const uint8_t *data;3uint32_t length;4};
This structure's properties are:
data
— A pointer to the header content. Do not terminate the header with <CR><LF>
.length
— The number of bytes in data
.Microvisor automatically adds a Host:
header for you. It also inserts a Content-Length:
header based on the size of any data you include. Again, you do not need to add this yourself, and if you do include one, it will be overwritten by Microvisor.
The maximum number of headers you may attach is 32. An MV_STATUS_TOOMANYELEMENTS
is issued for higher values.
This snippet from our sample HTTP code shows how we use mvSendHttpRequest()
to issue an HTTP request via the Microvisor cloud. The calls takes an MvHttpRequest
struct which defines the request. The function server_log()
is not included here, but can be viewed in the sample HTTP code.
1// Set up the request2unit32_t item_number = 1;3const char verb[] = "GET";4const char body[] = "";5char uri[46] = "";6sprintf(uri, "https://jsonplaceholder.typicode.com/todos/%u", item_number);7struct MvHttpHeader hdrs[] = {};8struct MvHttpRequest request_config = {9.method = {10.data = (uint8_t *)verb,11.length = strlen(verb)12},13.url = {14.data = (uint8_t *)uri,15.length = strlen(uri)16},17.num_headers = 0,18.headers = hdrs,19.body = {20.data = (uint8_t *)body,21.length = strlen(body)22},23.timeout_ms = 1000024};2526// Issue the request -- and check its status27enum MvStatus status = mvSendHttpRequest(http_handles.channel, &request_config);28if (status == MV_STATUS_OKAY) {29server_log("Request sent to the Microvisor cloud");30return true;31}
Read the status of an HTTP response
1extern enum MvStatus mvReadHttpResponseData(MvChannelHandle handle,2struct MvHttpResponseData *response_data);
Parameter | Description |
---|---|
handle | The handle of the channel that passed the source request. This must be a channel of type MV_CHANNELTYPE_HTTP |
response_data | A pointer to non-secure memory to which an MvHttpResponseData structure will be written by Microvisor |
Error Value | Description |
---|---|
MV_STATUS_PARAMETERFAULT | response_data does not reference memory accessible to the application |
MV_STATUS_INVALIDHANDLE | handle does not reference a valid channel of type MV_CHANNELTYPE_HTTP |
MV_STATUS_RESPONSENOTPRESENT | No HTTP response is present |
MV_STATUS_CHANNELCLOSED | The specified channel has already been closed |
Your application should call mvReadHttpResponseData()
when the HTTP channel receives a notification of type MV_EVENTTYPE_CHANNELDATAREADABLE
. Microvisor will write an MvHttpResponseData
record which your code can then parse:
1struct MvHttpResponseData {2enum MvHttpResult result;3uint32_t status_code;4uint32_t num_headers;5uint32_t body_length;6};
This structure's properties are:
result
— A value indicating the outcome of the request operation.status_code
— The standard HTTP status code returned.num_headers
— The number of headers in the response.body_length
— The length of the response body in bytes.The value written to the record's result
field will be one of the following:
Constant | Code Value | Description |
---|---|---|
MV_HTTPRESULT_OK | 0 | The HTTP request succeeded — but check the status code |
MV_HTTPRESULT_UNSUPPORTEDURISCHEME | 1 | An unsupported URI scheme, e.g., http:// , was used in the request |
MV_HTTPRESULT_UNSUPPORTEDMETHOD | 2 | An unsupported HTTP method was used in the request |
MV_HTTPRESULT_INVALIDHEADERS | 3 | Invalid headers were provided in the request |
MV_HTTPRESULT_INVALIDTIMEOUT | 4 | An invalid timeout was specified in the request (it should be in the range 5000-10000) |
MV_HTTPRESULT_REQUESTFAILED | 5 | The HTTP request failed |
MV_HTTPRESULT_RESPONSETOOLARGE | 6 | The HTTP response returned by the server (headers plus body) didn't fit into the HTTP channel's receive buffer |
This snippet from our sample HTTP code shows how we use mvReadHttpResponseData()
to access the response to a previously issued HTTP request. The functions server_log()
and server_error()
are not included here, but can be viewed in the sample HTTP code.
1static struct MvHttpResponseData resp_data;2enum MvStatus status = mvReadHttpResponseData(http_handles.channel, &resp_data);3if (status == MV_STATUS_OKAY) {4// Check we successfully issued the request (`result` is OK) and5// the request was successful (status code 200)6if (resp_data.result == MV_HTTPRESULT_OK) {7if (resp_data.status_code == 200) {8server_log("HTTP response header count: %lu", resp_data.num_headers);9server_log("HTTP response body length: %lu", resp_data.body_length);10} else {11server_error("HTTP status code: %lu", resp_data.status_code);12}13} else {14server_error("Request failed. Status: %i", resp_data.result);;15}16} else {17server_error("Response data read failed. Status: %i", status);18}
Read header data from an HTTP response
1extern enum MvStatus mvReadHttpResponseHeader(MvChannelHandle handle,2uint32_t header_index,3uint8_t *buffer,4uint32_t buffer_size);
Parameter | Description |
---|---|
handle | The handle of the channel that passed the source request. This must be a channel of type MV_CHANNELTYPE_HTTP |
header_index | The index of the header you require |
buffer | A pointer to non-secure memory into which the header will be written by Microvisor |
buffer_size | The size of the buffer in bytes |
Error Value | Description |
---|---|
MV_STATUS_PARAMETERFAULT | buffer does not reference memory accessible to the application |
MV_STATUS_INVALIDHANDLE | handle does not reference a valid channel of type MV_CHANNELTYPE_HTTP |
MV_STATUS_HEADERINDEXINVALID | The specified header index is greater the number of headers in the response - 1 |
MV_STATUS_RESPONSENOTPRESENT | No HTTP response is present |
MV_STATUS_CHANNELCLOSED | The specified channel has already been closed |
Your call to mvReadHttpResponseData()
will indicate the number of headers, if any, included in the response. To read one of these headers, call this function and pass in a header_index
value indicating the desired header's position in the sequence of headers. Microvisor will write the header into the buffer you specify in the call.
The following function demonstrates how you can use mvReadHttpResponseHeader()
to extract one or more headers from the response to a previously issued HTTP request and log them. The functions server_log()
and server_error()
are not included here, but can be viewed in our sample HTTP code.
1/**2* @brief Output all received headers.3*4* @param n: The number of headers to list.5*/6void output_headers(uint32_t n) {7if (n > 0) {8uint8_t buffer[2048];9for (uint32_t i = 0 ; i < n ; ++i) {10memset((void *)buffer, 0x00, 256);11enum MvStatus status = mvReadHttpResponseHeader(http_handles.channel, i, buffer, 2048);12if (status == MV_STATUS_OKAY) {13server_log("%lu. %s", i + 1, buffer);14} else {15server_error("Could not read header %lu", i + 1);16}17}18}19}
Read body data from an HTTP response
1extern enum MvStatus mvReadHttpResponseBody(MvChannelHandle handle,2uint32_t offset,3uint8_t *buffer,4uint32_t buffer_size);
Parameter | Description |
---|---|
handle | The handle of the channel that passed the source request. This must be a channel of type MV_CHANNELTYPE_HTTP |
offset | The byte offset from the start of the body to read from |
buffer | A pointer to non-secure memory into which the body data will be written by Microvisor |
buffer_size | The size of the buffer in bytes |
Error Value | Description |
---|---|
MV_STATUS_PARAMETERFAULT | buffer does not reference memory accessible to the application |
MV_STATUS_INVALIDHANDLE | handle does not reference a valid channel of type MV_CHANNELTYPE_HTTP |
MV_STATUS_OFFSETINVALID | The value of offset exceeds the size of the returned body |
MV_STATUS_RESPONSENOTPRESENT | No HTTP response is present |
MV_STATUS_CHANNELCLOSED | The specified channel has already been closed |
Your call to mvReadHttpResponseData()
will indicate the length of the response's body, if any. To read all or part of the body data, call this function.
To read just a portion of the body, set a non-zero value of offset
as the start byte and/or specify a buffer size below that of the response body's length. Microvisor will read from the response body from the byte at offset
up to the end of the target buffer.
This snippet from our sample HTTP code shows how we use mvReadHttpResponseBody()
to access the body data within the response to a previously issued HTTP request. See the mvReadHttpResponseData()
example for the code that wraps this stanza. The functions server_log()
and server_error()
are not included here, but can be viewed in the sample HTTP code.
1// Set up a buffer that we'll get Microvisor to write2// the response body into3uint8_t buffer[resp_data.body_length + 1];4memset((void *)buffer, 0x00, resp_data.body_length + 1);5status = mvReadHttpResponseBody(http_handles.channel, 0, buffer, resp_data.body_length);6if (status == MV_STATUS_OKAY) {7// Retrieved the body data successfully so log it8server_log("Message JSON:\n%s", buffer);9} else {10server_error("HTTP response body read status %i", status);11}