Etherios Cloud Connector very first porting for mbed. Tested in an LPC1768

Etherios Cloud Connector for Embedded v2.1.0.3 library for mbed. Early porting.

This port is centered mainly in the platform code. So it should work properly with the provided examples of send_data, device_request, data_points, RCI and firmware_update (stub implementation, not a real one... yet ;-)). Filesystem is not implemented yet, and some examples might need changes.

To run, it needs the following libraries: - mbed - mbed-rtos - EthernetInterface

Find more information (and the source code!) about Etherios Cloud Connector for Embedded here: http://www.etherios.com/products/devicecloud/support/connector and in: http://www.etherios.com

private/rci_binary_traverse.h

Committer:
spastor
Date:
2013-12-03
Revision:
0:1c358ea10753

File content as of revision 0:1c358ea10753:

/*
 * Copyright (c) 2013 Digi International Inc.,
 * All rights not expressly granted are reserved.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
 * =======================================================================
 */

static void traverse_rci_command(rci_t * const rci)
{
    trigger_rci_callback(rci, connector_request_id_remote_config_action_start);

    set_rci_output_state(rci, rci_output_state_command_id);
    state_call(rci, rci_parser_state_output);

}
static void traverse_group_id(rci_t * const rci)
{
    trigger_rci_callback(rci, connector_request_id_remote_config_group_start);

    set_rci_output_state(rci, rci_output_state_group_id);
    state_call(rci, rci_parser_state_output);
}

static void traverse_element_id(rci_t * const rci)
{

    connector_group_element_t const * const element = get_current_element(rci);

    if ((rci->shared.callback_data.action == connector_remote_action_query) &&
        (element->access == connector_element_access_write_only))
    {
        goto done;
    }

    trigger_rci_callback(rci, connector_request_id_remote_config_group_process);
    set_rci_output_state(rci, rci_output_state_field_id);
    state_call(rci, rci_parser_state_output);

done:
    return;
}

static void traverse_element_end(rci_t * const rci)
{
    trigger_rci_callback(rci, connector_request_id_remote_config_group_end);

    set_rci_output_state(rci, rci_output_state_field_terminator);
    state_call(rci, rci_parser_state_output);
}

static void traverse_group_end(rci_t * const rci)
{
    trigger_rci_callback(rci, connector_request_id_remote_config_action_end);
    set_rci_output_state(rci, rci_output_state_group_terminator);
    state_call(rci, rci_parser_state_output);

}

static connector_bool_t traverse_all_elements(rci_t * const rci)
{
    connector_bool_t done = connector_false;

    if (!have_element_id(rci))
    {
        /* all fields */
        set_element_id(rci, 0);
        traverse_element_id(rci);
    }
    else
    {
        connector_group_t const * const group =  get_current_group(rci);
        unsigned int const id = get_element_id(rci) + 1;

        if (id < group->elements.count)
        {
            set_element_id(rci, id);
            traverse_element_id(rci);
        }
        else
        {
            traverse_element_end(rci);
            done = connector_true;
        }
    }
    return done;
}

static connector_bool_t traverse_all_group_instances(rci_t * const rci)
{
    connector_bool_t done = connector_false;

    switch (rci->traverse.process_state)
    {
        case rci_traverse_process_group:
        case rci_traverse_process_element:
            if (traverse_all_elements(rci))
                rci->traverse.process_state = rci_traverse_process_next_instance;
            break;
        case rci_traverse_process_next_instance:
            {
                connector_group_t const * const group =  get_current_group(rci);
                if (group->instances > 1 && group->instances > get_group_index(rci))
                {
                    /* next instances */
                    increment_group_index(rci);
                    traverse_group_id(rci);
                    rci->traverse.process_state = rci_traverse_process_element;
                }
                else
                {
                    /* no more instances */
                    done = connector_true;
                }
            }
            break;
    }

    return done;
}

static connector_bool_t traverse_all_groups(rci_t * const rci)
{
    connector_bool_t done = connector_false;

    switch (rci->traverse.process_state)
    {
        case rci_traverse_process_group:
        {
            connector_remote_group_table_t const * const table = (connector_rci_config_data.group_table + rci->shared.callback_data.group.type);

            if (table->count == 0)
            {
                traverse_group_end(rci);
            }
            else if (!have_group_id(rci))
            {
                set_group_id(rci, 0);
                set_group_index(rci, 1);
                traverse_group_id(rci);
                rci->traverse.process_state = rci_traverse_process_element;
            }
            else
            {

                size_t const id = get_group_id(rci) + 1;

                if (id == table->count)
                {
                    /* done all groups */
                    traverse_group_end(rci);
                    done = connector_true;
                }
                else
                {
                    connector_group_t const * const group =  get_current_group(rci);
                    if (group->instances > 1 && group->instances > get_group_index(rci))
                    {
                        /* next instances */
                        increment_group_index(rci);
                    }
                    else
                    {
                        /* next group */
                        increment_group_id(rci);
                        set_group_index(rci, 1);
                    }
                    traverse_group_id(rci);
                    rci->traverse.process_state = rci_traverse_process_element;
                }
            }
            break;
        }
        case rci_traverse_process_element:
            if (traverse_all_elements(rci))
                rci->traverse.process_state = rci_traverse_process_group;
            break;

        case rci_traverse_process_next_instance:
            break;
    }

    return done;
}

static void rci_traverse_data(rci_t * const rci)
{
    connector_bool_t done_state = connector_true;

    rci_debug_printf("traverse: %s\n", rci_traverse_state_t_as_string(rci->traverse.state));

    switch (rci->traverse.state)
    {
        case rci_traverse_state_none:
            if (get_rci_input_state(rci) == rci_input_state_done)
                state_call(rci, rci_parser_state_output);
            else
                state_call(rci, rci_parser_state_input);
            break;

        case rci_traverse_state_command_id:
            traverse_rci_command(rci);
            break;

        case rci_traverse_state_all_groups:
            done_state = traverse_all_groups(rci);
            break;

        case rci_traverse_state_group_id:
            traverse_group_id(rci);
            break;

        case rci_traverse_state_all_group_instances:
            done_state = traverse_all_group_instances(rci);
            break;

        case rci_traverse_state_element_id:
            traverse_element_id(rci);
            break;

        case rci_traverse_state_all_elements:
            done_state = traverse_all_elements(rci);
            break;

        case rci_traverse_state_element_end:
            traverse_element_end(rci);
            break;

        case rci_traverse_state_group_end:
            traverse_group_end(rci);
            break;
    }

    if (done_state)
    {
        rci->traverse.process_state = rci_traverse_process_group;
        set_rci_traverse_state(rci, rci_traverse_state_none);
    }

    return;
}