<<< Previous: Creating Applications Part 1 - Nabto Queries and the Event Handling C Function
The event handler is called automatically each time a Nabto query is received. One of the handler's parameters is used to pass the query's request parameters into the C function, another parameter is used to pass any response parameters that might be generated out of the C function. The query ID is used to determine both the number of, and the format of, the request and response parameters.
Example implementations that handle the queries used in the live demo are provided on this page. /* * Parameters: * pxRequest A pointer to a structure that contains details of the query, * including the query's unique ID. * pxReadBuffer A buffer that contains the request parameters. Do not read from * the buffer directly. Access functions are provided. * pxWriteBuffer A buffer into which response parameters are written. Do not * write to the buffer directly. Access functions are provided. */ application_event_result_t application_event( application_request_t* pxRequest, buffer_read_t* pxReadBuffer, buffer_write_t* pxWriteBuffer ); Listing 1: The prototype of the FreeRTOS+Nabto application event handler
| Query ID #1: Get RTOS tick count | |
| Request Parameters: | None |
| Response Parameters: | The RTOS tick count value, transmitted as a 32-bit unsigned integer |
The source code that handles query #1 is shown in Listing 2.
Notes:
/* Define a text constant for query ID #1. */
#define sysQUERY_TICK_VALUE 1
/* The standard function prototype as shown in list 1. */
application_event_result_t application_event( application_request_t* pxRequest,
buffer_read_t* pxReadBuffer,
buffer_write_t* pxWriteBuffer )
{
application_event_result_t xReturn;
/*
* The bullet points directly above this code listing provide an explanation of
* the following code.
*/
switch( request->query_id )
{
case sysQUERY_TICK_VALUE:
/* Write the response parameter to pxWriteBuffer. */
if( buffer_write_uint32( pxWriteBuffer, xTaskGetTickCount() ) == pdFAIL )
{
/* The response parameter would not fit in the write buffer. */
xReturn = AER_REQ_RSP_TOO_LARGE;
}
else
{
/* The write buffer contains the value of the response parameter. */
xReturn = AER_REQ_RESPONSE_READY;
}
break;
}
return xReturn;
}
Listing 2: Source code to handle query #1
| Query ID #2: Get network statistic | |
| Request Parameters: | The ID of the statistic being queried, received as a 32-bit unsigned integer |
| Response Parameters: | The value of the network statistic that corresponds to the ID received as the request parameter, transmitted as a 32-bit unsigned integer |
The source code that handles query #2 is shown in Listing 3. The notes
above listing 2 are also relevant
to listing 3. In addition:
The value of the request parameter is set by the three radio buttons on the user interface. It is used to tell the networked device whether it should respond with:
prvGetNetworkStatistic() returns the value of the network statistic that corresponds to the value of the request parameter.
/* Define a text constant for query ID #2. */
#define sysQUERY_NET_STAT 2
/* The standard function prototype as shown in list 1. */
application_event_result_t application_event( application_request_t* pxRequest,
buffer_read_t* pxReadBuffer,
buffer_write_t* pxWriteBuffer )
{
application_event_result_t xReturn;
unsigned long ulRequestParameter, ulStatValue;
/*
* The bullet points directly above this code listing provide an explanation
* of the following code.
*/
switch( request->query_id )
{
case sysQUERY_NET_STAT:
/* Read the request parameter from pxReadBuffer. */
if( buffer_read_uint32( pxReadBuffer, &ulRequestParameter ) == pdFAIL )
{
/* There are two few bytes remaining in pxReadBuffer to complete the
read request. */
xReturn = AER_REQ_TOO_SMALL;
}
else
{
ulStatValue = prvGetNetworkStatistic( ulRequestParameter );
/* Write the response parameter to pxWriteBuffer. */
if( buffer_write_uint32( pxWriteBuffer, ulStatValue ) == pdFAIL )
{
/* The response parameter would not fit in the write buffer. */
xReturn = AER_REQ_RSP_TOO_LARGE;
}
else
{
/* The write buffer contains the value of the response parameter. */
xReturn = AER_REQ_RESPONSE_READY;
}
}
}
return xReturn;
}
Listing 3: Source code to handle query #2
| Query ID #3: FreeRTOS command console | |
| Request Parameters: | The command entered by the user, received as a raw data buffer |
| Response Parameters: | The ascii text generated when the received command was executed, transmitted as a raw data buffer |
The source code that handles query #3 is shown in Listing 4. The notes
above listing 2 and listing 3
are also relevant to listing 4. In addition:
/* Define a text constant for query ID #3. */
#define sysQUERY_COMMAND_STRING 3
/* Dimensions local buffers to be large enough to hold one line of input/output. */
#define sysMAX_LINE_LENGTH 128
/* The standard function prototype as shown in list 1. */
application_event_result_t application_event( application_request_t* pxRequest,
buffer_read_t* pxReadBuffer,
buffer_write_t* pxWriteBuffer )
{
application_event_result_t xReturn;
buffer_t xRawBuffer;
static uint8_t ucLocalBuffer[ sysMAX_LINE_LENGTH ];
/*
* The bullet points directly above this code listing provide an explanation
* of the following code.
*/
switch( request->query_id )
{
case sysQUERY_COMMAND_STRING:
/* The locally declared raw buffer is used to point to the locally
declared ucLocalBuffer array. */
xRawBuffer.data = ucLocalBuffer;
xRawBuffer.size = sizeof( ucLocalBuffer );
/* Read raw data from pxReadBuffer into the buffer pointed to by
pxReadBuffer (pxReadBuffer is pointing to ucLocalBuffer). */
if( buffer_read_raw( pxReadBuffer, &xRawBuffer ) != pdFALSE )
{
/* ucLocalBuffer now holds the command string. Ensure it is
terminated. */
ucLocalBuffer[ xRawBuffer.size ] = 0x00;
/* Execute the command. xRawBuffer is now set to point to the
output generated when the command was executed. */
xRawBuffer.data = prvProcessCommandString( ucLocalBuffer );
/* Update the length of data in the raw buffer to reflect the
length of the string it now contains. */
xRawBuffer.size = strlen( xRawBuffer.data );
/* Write the raw buffer to the output buffer. */
if( buffer_write_raw( pxWriteBuffer, &xRawBuffer ) == pdFALSE )
{
xReturn = AER_REQ_RSP_TOO_LARGE;
}
else
{
xReturn = AER_REQ_RESPONSE_READY;
}
}
else
{
xReturn = AER_REQ_TOO_SMALL;
}
break;
}
return xReturn;
}
Listing 4: Source code to handle query #3