utility/msgpack/read_write_stream.c
/*
* EVALUATION AND USE OF THIS SOFTWARE IS SUBJECT TO THE TERMS AND
* CONDITIONS OF THE CONTROLLING LICENSE AGREEMENT FOUND AT LICENSE.md
* IN THIS SDK. IF YOU DO NOT AGREE TO THE LICENSE TERMS AND CONDITIONS,
* PLEASE RETURN ALL SOURCE FILES TO SILICON LABORATORIES.
* (c) Copyright 2018, Silicon Laboratories Inc. All rights reserved.
*/
#include "common.h"
#define ADC_READINGS 5
#define TCP_ECHO_SERVER_HOST "test.zentri.com"
#define TCP_ECHO_SERVER_PORT 50007
typedef struct
{
gos_handle_t handle;
uint32_t bytes_written;
} write_context_t;
/*************************************************************************************************
* This demonstrates how to serialize/de-serialize a MessagePack data stream.
*
* The stream is written to a TCP echo server. i.e. everything that is written to the
* server is echoed back to the device.
*
* The format of the data this example uses is as follows:
* (Note: While described in JSON format, the data is actually MessagePack formatted)
*
* {
* "time-ms" : <uint64:time in ms>,
* "time-utc" : "<string: time as UTC string>",
* "tick" : <uint32: RTOS tick count>,
* "mac" : "<binary string: MAC address as binary string>",
* "gpio-list": [ <array:bool: gpio values> ],
* "adc-readings" : {
* "adc-X" :
* {
* "format" : "<string:mV/raw>",
* "value" : <uint32:value>
* }
* ...
* }
* }
*/
gos_result_t read_write_stream(void)
{
gos_result_t result;
uint32_t serialized_data_length = 0;
if (GOS_FAILED(result, gos_tcp_connect(gos_network_get_default_interface(), TCP_ECHO_SERVER_HOST, TCP_ECHO_SERVER_PORT, &handle)))
{
GOS_LOG("Failed to connect to TCP echo server. Err code: %d", result);
}
if (GOS_FAILED(result, serialize_data(handle, &serialized_data_length)))
{
GOS_LOG("Failed to serialize data. Err code: %d", result);
}
{
GOS_LOG("Failed to deserialize data. Err code: %d", result);
}
gos_tcp_disconnect(handle);
return result;
}
/*************************************************************************************************
* Serial data using MessagePack format
*/
{
write_context_t write_context =
{
.handle = handle,
.bytes_written = 0
};
MSGPACK_INIT_WITH_WRITER(serialize_context, tcp_stream_writer, &write_context);
// The root dictionary has 6 key/value pairs
// Write the current time
{
gos_utc_ms_t current_time_ms;
// Note: 'long' = 64bit
}
// Write UTC time
{
gos_iso8601_str_t current_time_utc;
GOS_VERIFY(gos_msgpack_write_dict_str(&serialize_context, "time-utc", (const char*)¤t_time_utc));
}
// Write current RTOS tick
{
// Note: 'int' = 32bit
}
// Write MAC address as binary string
{
char mac_str[24];
gos_mac_t mac_address;
str_to_mac(mac_str, &mac_address);
GOS_VERIFY(gos_msgpack_write_dict_bin(&serialize_context, "mac", mac_address.octet, sizeof(mac_address.octet)));
}
// Write the current value of all GPIOs as an array
{
// Write the array marker
// Write the array entries
{
}
}
// Write the ADCs object entries
{
// The sub-dictionary will have ADC_READINGS key/value pairs
for (int adc_reading_num = 0; adc_reading_num < ADC_READINGS; ++adc_reading_num)
{
uint16_t reading_value = 0;
char key_str[16];
//gos_adc_sample_type_t sample_type = ((adc_reading_num & 0x1) == 0) ? GOS_ADC_SAMPLE_TYPE_RAW : GOS_ADC_SAMPLE_TYPE_VOLTAGE;
const char *sample_type_str = ((adc_reading_num & 0x1) == 0) ? "raw" : "mV";
// Get the current value of the ADC
//gos_adc_sample(PLATFORM_STD_ADC, &reading_value, sample_type);
// Generate the entry key string
sprintf(key_str, "adc-%d", adc_reading_num);
// Write the adc sub-sub-dictionary which contains 2 entries
GOS_VERIFY(gos_msgpack_write_dict_dict(&serialize_context, key_str, 2));
// Write the 'format' entry
// Write the value entry
}
}
// Write one more time to flush the buffer
// Return the total length of the serialized buffer
*buffer_length_ptr = write_context.bytes_written;
}
/*************************************************************************************************
* Deserialize the msgpack formatted buffer and print the contents
*/
{
gos_result_t result;
gos_msgpack_object_t *root_ptr = NULL;
uint8_t *buffer = NULL;
{
GOS_LOG("Failed to alloc RX buffer");
goto exit;
}
{
GOS_LOG("Failed to read RX data. Err code: %d", result);
goto exit;
}
// Dump the 'packed' binary data
gos_dump_buffer(buffer, length, "'Packed' binary dump:", GOS_DUMP_FLAGS(16, 1, LITTLE, ADD_SPACE, PRINT_ADDRESSES, PRINT_ASCII));
{
GOS_LOG("Failed to deserialize msgpack buffer. Err code: %d", result);
goto exit;
}
// Retrieve and print the 'time-ms' entry
{
if(obj == NULL)
{
GOS_LOG("WARN: 'time-ms' entry not found");
}
else
{
char str_buffer[32];
uint64_t time_ms;
MSGPACK_ULONG(obj, &time_ms);
}
}
// Retrieve and print the 'time-utc' entry
{
if (obj == NULL)
{
GOS_LOG("WARN: 'time-utc' entry not found");
}
{
GOS_LOG("WARN: 'time-utc' entry is NOT a string object");
}
else
{
char str_buffer[32];
}
}
// Retrieve and print the 'tick' entry
{
if (obj == NULL)
{
GOS_LOG("WARN: 'tick' entry not found");
}
else
{
}
}
// Retrieve and print the 'mac' entry
{
if (obj == NULL)
{
GOS_LOG("WARN: 'mac' entry not found");
}
{
GOS_LOG("WARN: 'mac' entry is NOT a binary string object");
}
else
{
gos_mac_t mac_address;
char mac_str[20];
}
}
// Retrieve and print the 'gpio-list' entry
{
if (obj == NULL)
{
GOS_LOG("WARN: 'gpio-list' entry not found");
}
{
GOS_LOG("WARN: 'gpio-list' entry is NOT an array object");
}
else
{
{
if (entry == NULL)
{
GOS_LOG("WARN: 'gpio-list' entry not found");
}
{
GOS_LOG("WARN: 'gpio-list' entry is NOT a boolean object");
}
else
{
}
}
}
}
// Retrieve and print the 'adc-readings' entry
{
if (obj == NULL)
{
GOS_LOG("WARN: 'adc-readings' entry not found");
}
{
GOS_LOG("WARN: 'adc-readings' entry is NOT a dict object");
}
else
{
{
char key_str[16];
sprintf(key_str, "adc-%d", reading_num);
if (entry == NULL)
{
GOS_LOG("WARN: 'adc-readings' entry not found");
}
{
GOS_LOG("WARN: 'adc-readings' entry is NOT a dict object");
}
else
{
char format_str[8];
GOS_LOG("%s : %u (%s)", key_str, MSGPACK_UINT(value_entry), MSGPACK_STR(format_entry, format_str, sizeof(format_str)));
}
}
}
}
exit:
MSGPACK_FREE_OBJECTS(root_ptr);
if (buffer != NULL)
{
gos_free(buffer);
}
return result;
}
/*************************************************************************************************/
{
write_context_t *write_context = user;
write_context->bytes_written += length;
}
/*************************************************************************************************/
{
uint8_t *ptr = buffer;
while (length > 0)
{
uint32_t bytes_read;
{
{
continue;
}
else
{
break;
}
}
length -= bytes_read;
ptr += bytes_read;
}
return result;
}