cloud/coap_demo/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 "common.h"
#include "nvm_settings.h"
#include "coap_types.h"
#include "coap.h"
//#define DEBUG_COAP_APPLICATION
static coap_settings_t* settings;
coap_uri_t coap_uri;
char custom_path[MAX_PATH_LENGTH];
char payload[MAX_PAYLOAD_LENGTH];
bool observing = false;
static void coap_event_handler ( coap_event_t event, void *arg );
#ifdef DEBUG_COAP_APPLICATION
#define COUNTOF(a) (sizeof(a)/sizeof(a[0]))
typedef const struct
{
uint8_t value;
const uint8_t* const name;
} name_map;
static name_map coap_options[] =
{
{ COAP_NO_OPTION, (const uint8_t*) "NO OPTION"},
{ COAP_OPTION_IF_MATCH, (const uint8_t*) "IF MATCH"},
{ COAP_OPTION_URI_HOST, (const uint8_t*) "URI HOST"},
{ COAP_OPTION_ETAG, (const uint8_t*) "ETAG"},
{ COAP_OPTION_IF_NONE_MATCH, (const uint8_t*) "IF NONE MATCH"},
{ COAP_OPTION_OBSERVE, (const uint8_t*) "OBSERVE"},
{ COAP_OPTION_URI_PORT, (const uint8_t*) "URI PORT"},
{ COAP_OPTION_LOCATION_PATH, (const uint8_t*) "LOCATION PATH"},
{ COAP_OPTION_URI_PATH, (const uint8_t*) "URI PATH"},
{ COAP_OPTION_CONTENT_FORMAT, (const uint8_t*) "CONTENT FORMAT"},
{ COAP_OPTION_MAX_AGE, (const uint8_t*) "MAX AGE"},
{ COAP_OPTION_URI_QUERY, (const uint8_t*) "URI QUERY"},
{ COAP_OPTION_ACCEPT, (const uint8_t*) "ACCEPT"},
{ COAP_OPTION_LOCATION_QUERY, (const uint8_t*) "LOCATION QUERY"},
{ COAP_OPTION_BLOCK2, (const uint8_t*) "BLOCK2"},
{ COAP_OPTION_BLOCK1, (const uint8_t*) "BLOCK1"},
{ COAP_OPTION_SIZE2, (const uint8_t*) "SIZE2"},
{ COAP_OPTION_PROXY_URI, (const uint8_t*) "PROXY URI"},
{ COAP_OPTION_PROXY_SCHEME, (const uint8_t*) "PROXY SCHEME"},
{ COAP_OPTION_SIZE1, (const uint8_t*) "SIZE1"}
};
const char* coap_debug_get_option_string(coap_option_t option)
{
return lookup_name(option, coap_options, COUNTOF(coap_options));
}
static const char* lookup_name(uint8_t value, name_map *map, uint8_t count)
{
uint8_t i;
static char notfound[10];
for (i = 0; i < count; i++) {
if (map[i].value == value) {
return (const char*)map[i].name;
}
}
sprintf(notfound, "(%u)??", value);
return (const char*)notfound;
}
#else //DEBUG_COAP_APPLICATION
// static char dummy = 0;
#define coap_debug_get_option_string
// #define lookup_name(...) ((const char*)&dummy)
#endif //DEBUG_COAP_APPLICATION
/*************************************************************************************************/
void gos_app_init(void)
{
gos_result_t result;
if ( GOS_FAILED( result, coap_init( coap_event_handler ) ) )
{
GOS_LOG( "Failed to initialize CoAP: %d", result );
return;
}
/* Bring up the network interface */
{
GOS_LOG("Network is down, restarting...");
{
GOS_LOG("Failed to restart network: %d", result);
return;
}
}
commands_init();
if (GOS_FAILED(result, GOS_NVM_GET(COAP, DEMO, settings)))
{
GOS_LOG("Error retrieving settings");
}
else
{
coap_uri.host = settings->host;
coap_uri.port = settings->port;
coap_uri.path = settings->path;
GOS_LOG("CoAP Demo Application Started:");
GOS_LOG("Optional arguments surrounded by [brackets]");
GOS_LOG(" - List all variables : get coap");
GOS_LOG(" - Set variable <coap.var> to value <val> : set coap.var val");
GOS_LOG(" - Get a resource : coap_get [path]");
GOS_LOG(" - Discover a resource : coap_discover");
GOS_LOG(" - Put a resource : coap_put [path]");
GOS_LOG(" - Post (create) a resource : coap_post [path]");
GOS_LOG(" - Delete a resource : coap_delete [path]");
GOS_LOG(" - Observe a resource : coap_observe [path]");
GOS_LOG(" - Cancel observing a resource : coap_cancel");
}
}
/*************************************************************************************************/
void gos_app_deinit(void)
{
// This API is called just before the application finishes.
// Anything initialized or allocated by the app should be cleaned here.
// This API is optional.
}
/*
* Send a get request to a CoAP path.
*/
void coap_app_get( void* arg )
{
coap_uri.path = settings->path;
if ( strlen( custom_path ) != 0 )
{
coap_uri.path = custom_path;
}
GOS_LOG( "Getting resource %s:%u%s", settings->host, settings->port, coap_uri.path );
ret = coap_get( &coap_uri );
if ( ret != GOS_SUCCESS )
{
GOS_LOG( "Failed to get the resource (%d)", ret );
}
}
void coap_app_discover( void* arg )
{
GOS_LOG( "Discovering resource(s) %s:%u", settings->host, settings->port );
ret = coap_discover( &coap_uri );
if ( ret != GOS_SUCCESS )
{
GOS_LOG( "Failed to discover the URI." );
}
}
void coap_app_put( void* arg )
{
coap_uri.path = custom_path;
GOS_LOG( "Putting %s at %s:%u%s", payload, settings->host, settings->port, coap_uri.path );
ret = coap_put( &coap_uri, payload );
if ( ret != GOS_SUCCESS )
{
GOS_LOG( "Failed to put the resource." );
}
}
void coap_app_post( void* arg )
{
coap_uri.path = custom_path;
GOS_LOG( "Posting %s at %s:%u%s", payload, settings->host, settings->port, coap_uri.path );
ret = coap_post( &coap_uri, payload );
if ( ret != GOS_SUCCESS )
{
GOS_LOG( "Failed to post the resource." );
}
}
void coap_app_delete( void* arg )
{
coap_uri.path = settings->path;
if ( strlen( custom_path ) != 0 )
{
coap_uri.path = custom_path;
}
GOS_LOG( "Deleting resource from %s:%u%s", settings->host, settings->port, coap_uri.path );
ret = coap_delete( &coap_uri );
if ( ret != GOS_SUCCESS )
{
GOS_LOG( "Failed to delete the resource." );
}
}
void coap_app_observe( void* arg )
{
coap_uri.path = settings->path;
if ( strlen( custom_path ) != 0 )
{
coap_uri.path = custom_path;
}
GOS_LOG( "Observing resource: %s:%u%s", settings->host, settings->port, coap_uri.path );
ret = coap_observe( &coap_uri );
observing = true;
if ( ret != GOS_SUCCESS )
{
GOS_LOG( "Failed to observe the resource(%d).", ret );
}
}
void coap_app_cancel( void* arg )
{
GOS_LOG( "Cancelling observing resource: %s:%u", settings->host, settings->port );
ret = coap_cancel();
observing = false;
if ( ret != GOS_SUCCESS )
{
GOS_LOG( "Failed to cancel observing the resource." );
}
}
static void print_data( coap_message_t* message )
{
gos_write_log( "Received payload: ", strlen("Received payload: ") );
gos_write_log( (const char*) message->payload.pointer, message->payload.length );
}
static void print_options( coap_options_list_t* options, uint8_t count )
{
GOS_LOG( "Options (%u):", count );
for (uint8_t i=0; i<count; i++)
{
GOS_LOG("option: %s(%u), len: %u", coap_debug_get_option_string(options[i].code), options[i].code, options[i].value.length);
}
}
static void coap_event_handler ( coap_event_t event, void *arg )
{
coap_message_t* message;
switch ( event )
{
case COAP_EVENT_ACK_RECEIVED: GOS_LOG( "Ack received" ); break;
case COAP_EVENT_ACK_TIMEOUT: GOS_LOG( "Ack timeout" ); break;
case COAP_EVENT_DATA_RECEIVED:
message = ( coap_message_t* )arg;
print_options( message->options, message->options_count );
print_data(message);
break;
default: break;
}
}