utility/profiler/main.c

/*******************************************************************************
* # License
* Copyright 2019 Silicon Laboratories Inc. www.silabs.com
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#include "gos.h"
#include "example_app_util.h"
#include "profiler.h"
#define EXAMPLE_URL "https://google.com"
// TLS CA certificate of HTTP URL
#define EXAMPLE_URL_CERT "globalsign_ca.crt"
#define APPLICATION_START_LINE "Profiler example starting..."
#define INVOKE_STATE(state) gos_event_issue(process_next_state, (void*)APP_STATE_ ## state, GOS_EVENT_FLAG_NONE)
typedef enum
{
APP_STATE_NONE,
APP_STATE_PROFILE_NETWORK_UP,
APP_STATE_PROFILE_HTTP_REQUEST,
APP_STATE_PRINT_PROFILER_STATUS
} app_state_t;
static bool processing_start = false;
static const char* const app_state_str[] =
{
[APP_STATE_NONE] = "None",
[APP_STATE_PROFILE_NETWORK_UP] = "Network Up",
[APP_STATE_PROFILE_HTTP_REQUEST] = "HTTP Request",
[APP_STATE_PRINT_PROFILER_STATUS] = "Print Status"
};
static const gos_handler_t app_state_handlers[] =
{
[APP_STATE_PROFILE_NETWORK_UP] = profile_network_up_state_handler,
[APP_STATE_PROFILE_HTTP_REQUEST] = profile_http_request_state_handler,
[APP_STATE_PRINT_PROFILER_STATUS] = print_status_state_handler
};
GOS_CMD_CREATE_COMMAND(example, start, "example_start", "start", 0, 0, true);
GOS_CMD_CREATE_COMMAND(example, stop, "example_stop", "stop", 0, 0, true);
/*************************************************************************************************
* Starting point for app
*/
void gos_app_init(void)
{
GOS_LOG(APPLICATION_START_LINE);
// Register all the profilers
// Attempt to print the network up on the default interface
example_app_util_network_up(GOS_INTERFACE_DEFAULT, false, network_event_handler);
}
/*************************************************************************************************
* Invoked when network is initially brought up
*/
static void network_event_handler(bool is_up)
{
if(is_up)
{
// Unregister the network_event_handler
processing_start = true;
GOS_LOG("Hint: Issue the command:\r\nexample_stop\r\nto stop the processing loop");
// If the loop hasn't started then start it now
INVOKE_STATE(PROFILE_NETWORK_UP);
}
}
/*************************************************************************************************
* Process the next app state
*/
static void process_next_state(void *state)
{
const app_state_t next_state = (app_state_t)(uint32_t)state;
if(!processing_start)
{
return;
}
GOS_LOG("Processing app state: %s", app_state_str[next_state]);
app_state_handlers[next_state](NULL);
}
/*************************************************************************************************
* Bring up network and profile time it takes to do so
*/
static void profile_network_up_state_handler(void *unused)
{
gos_result_t result;
// Bring down the network if it's already up
// Start the NETWORK_UP profiler
PROFILER_BEGIN("NETWORK_UP");
// Attempt to bring up the network
{
GOS_LOG("Failed to bring network up, err:%d", result);
}
// Stop the NETWORK_UP profiler
PROFILER_END("NETWORK_UP");
// Invoke the next state
INVOKE_STATE(PROFILE_HTTP_REQUEST);
}
/*************************************************************************************************
* Issue HTTP request and profile time it takes to do so
*/
static void profile_http_request_state_handler(void *unused)
{
gos_result_t result;
{
.method = GOS_HTTP_GET,
.url = EXAMPLE_URL,
.certs.ca = EXAMPLE_URL_CERT
};
GOS_LOG("Issuing HTTP request ... ");
// Start the HTTP profiler
PROFILER_BEGIN("HTTP");
// Start the HTTP_OPEN profiler
PROFILER_BEGIN("HTTP_OPEN");
result = gos_http_open_request(&request, &handle);
// Stop the HTTP_OPEN profiler
PROFILER_END("HTTP_OPEN");
// Exit on failure
if(result != GOS_SUCCESS)
{
GOS_LOG("Request failed: %d", result);
goto exit;
}
GOS_LOG("Receiving response ... ");
// Start the HTTP_RESPONSE profiler
PROFILER_BEGIN("HTTP_RESPONSE");
result = gos_http_receive_response(handle, &response);
// Stop the HTTP_OPEN profiler
PROFILER_END("HTTP_RESPONSE");
// Exit on failure
if(result != GOS_SUCCESS)
{
GOS_LOG("Response failed: %d", result);
goto exit;
}
GOS_LOG("Response code: %d", response.code);
GOS_LOG("Response length: %d", response.content_length);
// Start the HTTP_READ profiler
PROFILER_BEGIN("HTTP_READ");
for(;;)
{
gos_buffer_t buffer =
{
.size = UINT16_MAX
};
if(GOS_FAILED(result, gos_http_read_with_buffer(handle, &buffer)))
{
break;
}
}
// Stop the HTTP_READ profiler
PROFILER_END("HTTP_READ");
exit:
// Start the HTTP_CLOSE profiler
PROFILER_BEGIN("HTTP_CLOSE");
gos_http_close(handle);
// Stop the HTTP_CLOSE profiler
PROFILER_END("HTTP_CLOSE");
// Stop the HTTP profiler
PROFILER_END("HTTP");
// Invoke the next state
INVOKE_STATE(PRINT_PROFILER_STATUS);
}
/*************************************************************************************************
* Print the status of all profilers to log bus
*/
static void print_status_state_handler(void *unused)
{
// Print all profiler statuses to log bus
// Restart the loop
INVOKE_STATE(PROFILE_NETWORK_UP);
}
/*************************************************************************************************/
gos_cmd_result_t example_start_command(int argc, char **argv)
{
GOS_LOG("\r\nRestarting example. Issue the command:\r\\r\n nexample_stop\r\n\r\nTo stop the example");
// Reset all profilers
processing_start = true;
// Restart the loop
INVOKE_STATE(PROFILE_NETWORK_UP);
}
/*************************************************************************************************/
gos_cmd_result_t example_stop_command(int argc, char **argv)
{
GOS_LOG("\r\nStopping example. Issue the command:\r\n\r\n example_start\r\n\r\nTo restart the example");
processing_start = false;
}