Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
src/Helium.cpp
- Committer:
- Marc Nijdam
- Date:
- 2017-09-05
- Revision:
- 23:cc2c1d1ed159
- Parent:
- 20:d55e9eb828d4
File content as of revision 23:cc2c1d1ed159:
#include "Helium.h" #include "helium-client/helium-client.h" bool helium_serial_readable(void * param) { BufferedSerial * serial = (BufferedSerial *)param; return serial->readable() > 0; } bool helium_serial_getc(void * param, uint8_t * ch) { BufferedSerial * serial = (BufferedSerial *)param; int val = serial->getc(); *ch = val; return val >= 0; } bool helium_serial_putc(void * param, uint8_t ch) { BufferedSerial * serial = (BufferedSerial *)param; serial->putc(ch); return true; } void helium_wait_us(void * param, uint32_t us) { (void)param; wait_us(us); } Helium::Helium(PinName tx, PinName rx) : serial(tx, rx, 9600) { helium_init(&_ctx, (void *)&serial); } int Helium::baud(enum helium_baud baud) { int result = helium_baud(&_ctx, baud); uint32_t serial_baud = 9600; switch (baud) { case helium_baud_b9600: serial_baud = 9600; break; case helium_baud_b14400: serial_baud = 14400; break; case helium_baud_b19200: serial_baud = 19200; break; case helium_baud_b38400: serial_baud = 38400; break; case helium_baud_b57600: serial_baud = 57600; break; case helium_baud_b115200: serial_baud = 115200; break; } serial.baud(serial_baud); return result; } int Helium::info(struct helium_info * info) { return helium_info(&_ctx, info); } int Helium::connect(struct connection * connection, uint32_t retries) { return helium_connect(&_ctx, connection, retries); } bool Helium::connected() { return helium_connected(&_ctx) == helium_connected_CONNECTED; } int Helium::sleep(struct connection * connection) { return helium_sleep(&_ctx, connection); } bool Helium::needs_reset() { return helium_needs_reset(&_ctx); } int Helium::reset() { return helium_reset(&_ctx); } // // Channel // Channel::Channel(Helium * h) { helium = h; } int Channel::begin(const char * name, uint16_t * token) { return helium_channel_create(&helium->_ctx, name, strlen(name), token); } int Channel::begin(const char * name, int8_t * result) { uint16_t token; int status = begin(name, &token); _channel_id = -1; if (helium_status_OK == status) { status = poll_result(token, &_channel_id); } if (result) { *result = status == helium_status_OK && _channel_id > 0 ? 0 : _channel_id; } return status; } int Channel::send(void const * data, size_t len, uint16_t * token) { return helium_channel_send(&helium->_ctx, _channel_id, data, len, token); } int Channel::send(void const * data, size_t len, int8_t * result) { uint16_t token; int status = send(data, len, &token); if (helium_status_OK == status) { status = poll_result(token, result); } return status; } int Channel::poll_result(uint16_t token, int8_t * result, uint32_t retries) { return helium_channel_poll_result(&helium->_ctx, token, result, retries); } int Channel::poll_data(void * data, size_t len, size_t * used, uint32_t retries) { return helium_channel_poll_data(&helium->_ctx, _channel_id, data, len, used, retries); } // // Config // Config::Config(Channel * channel) { _channel = channel; } int Config::get(const char * key, uint16_t * token) { return helium_channel_config_get(&_channel->helium->_ctx, _channel->_channel_id, key, token); } int Config::_get(const char * config_key, enum helium_config_type config_type, void * value, size_t value_len, void * default_value, size_t default_value_len, uint32_t retries) { uint16_t token; int status = get(config_key, &token); int8_t result = 0; if (helium_status_OK == status) { status = poll_get_result(token, config_key, config_type, value, value_len, default_value, default_value_len, &result, retries); } if (helium_status_OK == status && result != 0) { status = helium_status_ERR_COMMUNICATION; } return status; } /** Context for the poll_get handlder * * An instance of this if filled in the #Config::poll_get_result * implementation and the result of the poll handler is returned in * the status field */ struct _poll_get_context { //! The config key to look for const char * filter_key; //! The config type to check for enum helium_config_type filter_type; //! The destination buffer void * dest; //! The length of the destination buffer size_t dest_len; //! The default value. Assumed to be the same type as filter_type void * default_value; //! The length of the default_value size_t default_value_len; //! The result status of the result handler enum config_poll_get_status status; }; static bool _poll_get_result_handler(void * handler_ctx, const char * key, enum helium_config_type value_type, void * value) { struct _poll_get_context * ctx = (struct _poll_get_context *)handler_ctx; size_t len = ctx->dest_len; void * src = value; if (strcmp(ctx->filter_key, key) != 0) { // Not the right key, keep going return true; } if (value_type == ctx->filter_type) { // Found and the right type // Use the given value and the destination buffer size ctx->status = config_status_POLL_FOUND; } else { // Found but not the right type, return an error ctx->status = config_status_POLL_ERR_TYPE; // And use the context's default value_type = ctx->filter_type; // Us the default value as the source src = ctx->default_value; // Check for a shorter default value length (only really valid for // strings) len = len > ctx->default_value_len ? ctx->default_value_len : len; } switch (value_type) { case helium_config_bool: case helium_config_f32: case helium_config_i32: case helium_config_str: break; case helium_config_null: ctx->status = config_status_POLL_FOUND_NULL; len = 0; break; } memcpy(ctx->dest, src, len); return false; } int Config::poll_get_result(uint16_t token, const char * config_key, helium_config_type config_type, void * value, size_t value_len, void * default_value, size_t default_value_len, int8_t * result, uint32_t retries) { struct _poll_get_context handler_ctx = { .filter_key = config_key, .filter_type = config_type, .dest = value, .dest_len = value_len, .default_value = default_value, .default_value_len = default_value_len, .status = config_status_POLL_FOUND_NULL, }; int status = helium_channel_config_get_poll_result(&_channel->helium->_ctx, token, _poll_get_result_handler, &handler_ctx, result, retries); if (helium_status_OK == status) { status = handler_ctx.status; } return status; } int Config::set(const char * config_key, helium_config_type config_type, void * value, uint16_t * token) { return helium_channel_config_set(&_channel->helium->_ctx, _channel->_channel_id, config_key, config_type, value, token); } int Config::poll_set_result(uint16_t token, int8_t * result, uint32_t retries) { return helium_channel_config_set_poll_result(&_channel->helium->_ctx, token, result, retries); } int Config::_set(const char * config_key, enum helium_config_type value_type, void * value, uint32_t retries) { uint16_t token; int status = set(config_key, value_type, value, &token); int8_t result = 0; if (helium_status_OK == status) { status = poll_set_result(token, &result, retries); } if (helium_status_OK == status && result != 0) { status = helium_status_ERR_COMMUNICATION; } return status; } bool Config::is_stale() { bool result = false; helium_channel_config_poll_invalidate(&_channel->helium->_ctx, _channel->_channel_id, &result, 0); return result; }