SWRU455M February 2017 – October 2020 CC3120 , CC3120MOD , CC3130 , CC3135 , CC3135MOD , CC3220MOD , CC3220MODA , CC3220R , CC3220S , CC3220SF , CC3230S , CC3230SF , CC3235MODAS , CC3235MODASF , CC3235MODS , CC3235MODSF , CC3235S , CC3235SF
The host may choose to send the resource as a single chunk as part of the response from the handler (the payload fields in the ResponseData structure), or split it across multiple fragments. Fragmentation must be used to transfer resources larger than 1500 bytes (this is also the maximal size of a single fragment). Without fragmentation, the entire resource data is sent as part of the response from the handler. With fragmentation, the handler does not return anything but the pending status, while the fragments of the response are sent using the sl_NetAppSend API. Each fragment may be a different size (but smaller than 1500 bytes). While there are more fragments to send, the SL_NETAPP_REQUEST_RESPONSE_FLAGS_CONTINUATION bit must be set in the flags parameter of the API. On the last fragment, this bit must be zero. The first call to sl_NetAppSend API must carry the metadata (HTTP headers) of the response. For that, the SL_NETAPP_REQUEST_RESPONSE_FLAGS_METADATA bit must be set in the flags parameter of the API. Figure 10-11 demonstrates the handling of a GET request without (1) and with (2) fragmentation.
The following code demonstrates how to implement an HTTP GET handler that sends a response (a short text string) immediately. The code assumes that the macro slcb_NetAppRequestHdlr is mapped to NetAppRequestHandler in file user.h.
#define RESPONSE_TEXT "Example text to be displayed in browser"
void NetAppRequestHandler( SlNetAppRequest_t *pNetAppRequest,
SlNetAppResponse_t *pNetAppResponse)
{
char *contentType = "text/html";
unsigned char *pMetadata;
unsigned char *pResponseText;
pMetadata = (unsigned char*)malloc(128);
pResponseText = (unsigned char*)malloc(sizeof(RESPONSE_TEXT));
if ((NULL == pMetadata) || (NULL == pResponseText))
{
/* Allocation error */
}
memcpy(pResponseText, RESPONSE_TEXT, sizeof(RESPONSE_TEXT));
switch(pNetAppRequest->Type)
{
case SL_NETAPP_REQUEST_HTTP_GET:
{
pNetAppResponse->Status = SL_NETAPP_HTTP_RESPONSE_200_OK;
/* Write the content type TLV to buffer */
pNetAppResponse->ResponseData.pMetadata = pMetadata;
*pMetadata =
(_u8) SL_NETAPP_REQUEST_METADATA_TYPE_HTTP_CONTENT_TYPE;
pMetadata++;
*(_u16 *)pMetadata = (_u16) strlen (contentType);
pMetadata+=2;
memcpy (pMetadata, contentType, strlen(contentType));
pMetadata+=strlen(contentType);
/* Write the content length TLV to buffer */
*pMetadata = SL_NETAPP_REQUEST_METADATA_TYPE_HTTP_CONTENT_LEN;
pMetadata++;
*(_u16 *)pMetadata = 2;
pMetadata+=2;
*(_u16 *) pMetadata = (_u16) sizeof(RESPONSE_TEXT);
pMetadata+=2;
/* Calculate and write the total length of meta data */
pNetAppResponse->ResponseData.MetadataLen =
pMetadata - pNetAppResponse->ResponseData.pMetadata;
/* Write the text of the response */
pNetAppResponse->ResponseData.PayloadLen = sizeof(RESPONSE_TEXT);
pNetAppResponse->ResponseData.pPayload = pResponseText;
pNetAppResponse->ResponseData.Flags = 0;
}
break;
default:
/* POST/PUT/DELETE requests will reach here. */break;
}
}
The following code demonstrates how to implement HTTP GET handler that delegates the request to some other application. The user must extract any relevant information from the request and save it as the data buffers are freed when the handler returns.
void NetAppRequestHandler( SlNetAppRequest_t *pNetAppRequest,
SlNetAppResponse_t *pNetAppResponse)
{
switch(pNetAppRequest->Type)
{
case SL_NETAPP_REQUEST_HTTP_GET:
{
/* Prepare pending response */
pNetAppResponse->Status = SL_NETAPP_RESPONSE_PENDING;
pNetAppResponse->ResponseData.pMetadata = NULL;
pNetAppResponse->ResponseData.MetadataLen = 0;
pNetAppResponse->ResponseData.pPayload = NULL;
pNetAppResponse->ResponseData.PayloadLen = 0;
pNetAppResponse->ResponseData.Flags = 0;
/* Copy to some global buffer any relevant info from pNetAppRequest (the handle
In particular) and signal the user application that a new HTTP request has arrived. */
}
break;
default:
/* POST/PUT/DELETE requests will reach here. */break;
}
}
When signaled, the user application can then send this suggested response:
#define RESPONSE_TEXT "Example text part 1 --- "
#define RESPONSE_TEXT2 "Example text part 2"
_u8 *metadataBuff;
_u8 *pResponseText;
_u8 *pMetadata;
_u16 MetadataLen = 0;
const _u8 *contentType = "text/html";
_u8 Flags = 0;
_u16 TextLength;
metadataBuff = (_u8 *) malloc (128);
pMetadata = metadataBuff;
/* HTTP status is sent as part of the meta-data*/
*pMetadata = (_u8) SL_NETAPP_REQUEST_METADATA_TYPE_STATUS;
pMetadata++;
*(_u16 *)pMetadata = (_u16) 2;
pMetadata+=2;
*(_u16 *)pMetadata = (_u16) SL_NETAPP_HTTP_RESPONSE_200_OK;
pMetadata+=2;
/* Write the content type TLV to buffer */
*pMetadata = (_u8) SL_NETAPP_REQUEST_METADATA_TYPE_HTTP_CONTENT_TYPE;
pMetadata++;
*(_u16 *)pMetadata = (_u16) strlen((char*)contentType);
pMetadata+=2;
memcpy (pMetadata, contentType, strlen((char*)contentType));
pMetadata+=strlen((char*)contentType);
/* Write the content length TLV to buffer */
*pMetadata = SL_NETAPP_REQUEST_METADATA_TYPE_HTTP_CONTENT_LEN;
pMetadata++;
*(_u16 *)pMetadata = 2;
pMetadata+=2;
TextLength = sizeof(RESPONSE_TEXT) + sizeof(RESPONSE_TEXT2);
*(_u16 *) pMetadata = TextLength;
pMetadata+=2;
MetadataLen = pMetadata - metadataBuff;
/* First send the meta-data (note the METADATA flag).
Continuation flag indicates there are more fragments to follow.
gHandle is assumed to be populated by the handler. */
Flags |= SL_NETAPP_REQUEST_RESPONSE_FLAGS_CONTINUATION;
Flags |= SL_NETAPP_REQUEST_RESPONSE_FLAGS_METADATA;
sl_NetAppSend (gHandle, MetadataLen, metadataBuff, Flags);
/* Send first data fragment. Continuation flag still
indicates there are more fragments to follow, */
Flags = SL_NETAPP_REQUEST_RESPONSE_FLAGS_CONTINUATION;
pResponseText = (_u8 *) malloc (sizeof(RESPONSE_TEXT));
memcpy(pResponseText, RESPONSE_TEXT, sizeof(RESPONSE_TEXT));
sl_NetAppSend (gHandle, sizeof(RESPONSE_TEXT), pResponseText, Flags);
/* Last data fragment - continuation flag is cleared. */
Flags = 0;
pResponseText = (_u8 *) malloc (sizeof(RESPONSE_TEXT2));
memcpy(pResponseText, RESPONSE_TEXT2, sizeof(RESPONSE_TEXT2));
sl_NetAppSend (gHandle, sizeof(RESPONSE_TEXT2), pResponseText, Flags);