Erick / Mbed 2 deprecated ICE_BLE_TEST

Dependencies:   NaturalTinyShell_ice libmDot-12Sept mbed-rtos mbed

Fork of ICE by Erick

src/ConfigurationHandler/ConfigurationHandler.cpp

Committer:
jmarkel44
Date:
2016-09-01
Revision:
1:057d8fc6cb2f
Parent:
0:65cfa4873284
Child:
2:da28f21b72a1

File content as of revision 1:057d8fc6cb2f:

/******************************************************************************
 *
 * File:                ConfigurationHandler.cpp
 * Desciption:          source for the ICE Configuration Handler
 *
 *****************************************************************************/
#include <stdio.h>
#include "global.h"
#include "rtos.h"
#include "ConfigurationHandler.h"
#include <map>
#include <string>

using namespace std;

extern osThreadId mainThreadId;

// local functions
static void     loadPersistentControls( void );
static void     createHandler ( const Message_t * );
static void     modifyHandler ( const Message_t * );
static void     destroyHandler( const Message_t * );
static void     displayThreadTable( void );

// control spawners
static Thread*  spawnNewTimerControl( const char * );
static Thread*  spawnNewPIDControl( const char * );
static Thread*  spawnNewSetpointControl( const char * );
static Thread*  spawnNewCompositeControl(const char *);
static Thread*  spawnNewManualControl(const char *);

// control thread table
typedef map<string, Thread *> StringThreadMap;
static StringThreadMap threadTable;

/*****************************************************************************
 * Function:             ConfigurationHandler
 * Description:          entry point for the configuration handler
 *
 * @param                (IN) args (user-defined arguments)
 * @return               none
 *****************************************************************************/
void ConfigurationHandler(void const *args)
{
    int rc;
    printf("\r%s is started...\n", __func__);

    //loadPersistentControls();

    osSignalSet(mainThreadId, sig_continue);

    while (true) {
        // wait for a message from a data handler
        osEvent evt = MailBox.get();
        if (evt.status == osEventMail) {
            Message_t *msg = (Message_t*)evt.value.p;
            switch (msg->action) {
                case ACTION_CREATE:
                    createHandler(msg);
                    break;
                case ACTION_MODIFY:
                    modifyHandler(msg);
                    break;
                case ACTION_DESTROY:
                    destroyHandler(msg);
                    break;
                default:
                    printf("\r\n%s: ERROR\n", __FUNCTION__);
                    rc = -1;
                    break;
            }

            if ( rc != 0 ) {
                // do something
            }

            // free the allocated memory for the message
            MailBox.free(msg);
        }
    }
}

/*****************************************************************************
 * Function:             ConfigurationHandler_DisplayThreads
 * Description:          Display list of active threads
 *
 * @param                none
 * @return               none
 *****************************************************************************/
void ConfigurationHandler_DisplayThreads(void)
{
    displayThreadTable();
}
/*****************************************************************************
 * Function:             loadPersistentControls
 * Description:          Create a new control thread
 *
 * @param                (IN) msg (parsed message data from the cloud)
 * @return               none
 *****************************************************************************/
static void loadPersistentControls(void)
{
    printf("\r%s no-op\n", __func__);
}

/*****************************************************************************
 * Function:             createHandler
 * Description:          Create a new control thread
 *
 * @param                (IN) msg (parsed message data from the cloud)
 * @return               none
 *****************************************************************************/
static void createHandler(const Message_t *msg)
{
    printf("\r\n%s: invoked with %s [%u]\n",
           __func__, msg->controlFile, msg->control);
    
    switch (msg->control) {
        case CONTROL_TIMER: {
            Thread *t = spawnNewTimerControl(msg->controlFile);
            threadTable[msg->controlFile] = t;
            break;
        }
        case CONTROL_PID: {
            Thread *t = spawnNewPIDControl(msg->controlFile);
            threadTable[msg->controlFile] = t;
            break;
        }
        case CONTROL_SETPOINT: {
            Thread *t = spawnNewSetpointControl(msg->controlFile);
            threadTable[msg->controlFile] = t;
            break;
        }
        case CONTROL_COMPOSITE: {
            Thread *t = spawnNewCompositeControl(msg->controlFile);
            threadTable[msg->controlFile] = t;
            break;
        }
        case CONTROL_MANUAL: {
            Thread *t = spawnNewManualControl(msg->controlFile);
            threadTable[msg->controlFile] = t;
            break;
        }
        default:
            printf("%s: unkown control type (%u)", __func__, msg->control);
            break;
    }
}

/*****************************************************************************
 * Function:             modifyHandler
 * Description:          modify an existing control thread
 *
 * @param                (IN) args (user-defined arguments)
 * @return               none
 *****************************************************************************/
static void modifyHandler(const Message_t *msg)
{
    // STUBBED
    printf("\r\n%s: invoked with %s\n", __FUNCTION__, msg->controlFile);
}

/*****************************************************************************
 * Function:             destroyHandler
 * Description:          detroy an existing control thread
 *
 * @param                (IN) args (user-defined arguments)
 * @return               none
 *****************************************************************************/
static void destroyHandler(const Message_t *msg)
{
    printf("\r\n%s: invoked with %s\n", __FUNCTION__, msg->controlFile);

    StringThreadMap::iterator pos;

    // find the control thread, terminate it, then delete the entry
    // from the thread table.
    pos = threadTable.find(msg->controlFile);
    if ( pos != threadTable.end() ) {
        Thread *t = pos->second;
        t->terminate();
        // perform cleanup
        delete t;
        // remove the entry from the map
        threadTable.erase(pos);
    }
}

static Thread *spawnNewTimerControl( const char *controlFile)
{
    // TODO: Be sure to free these args when the thread dies 
    Args_t *args = (Args_t*)malloc(sizeof(Args_t));
    
    strncpy(args->controlFile, controlFile, sizeof(args->controlFile));
    args->reserved = 0;
    
    Thread *t = new Thread(TimerControl, (void *)args);
    return t;
}
static Thread*  spawnNewPIDControl( const char *controlFile )
{
    Args_t *args = (Args_t *)malloc(sizeof(Args_t));
    
    strncpy(args->controlFile, controlFile, sizeof(args->controlFile));
    args->reserved = 0;
    
    Thread *t = new Thread(PIDControl, (void *)args);
    return t;
}

static Thread*  spawnNewSetpointControl( const char *controlFile )
{
    Args_t *args = (Args_t *)malloc(sizeof(Args_t));
    
    strncpy(args->controlFile, controlFile, sizeof(args->controlFile));
    args->reserved = 0;
    
    Thread *t = new Thread(SetpointControl, (void *)args);
    return t;
}

static Thread* spawnNewCompositeControl(const char *controlFile)
{
    Args_t *args = (Args_t *)malloc(sizeof(Args_t));
    
    strncpy(args->controlFile, controlFile, sizeof(args->controlFile));
    args->reserved = 0;

    Thread *t = new Thread(CompositeControl, (void *)args);
    return t;
}

static Thread*  spawnNewManualControl(const char *controlFile)
{
    Args_t *args = (Args_t *)malloc(sizeof(Args_t));
    
    strncpy(args->controlFile, controlFile, sizeof(args->controlFile));
    args->reserved = 0;

    Thread *t = new Thread(ManualControl, (void *)args);
    return t;
}

/*****************************************************************************
 * Function:             displayThreadTable
 * Description:          display the elements in the thread table
 *
 * @param                (IN) controlFile: file which to control fome
 * @return               osThreadId
 *****************************************************************************/
static void displayThreadTable(void)
{
    StringThreadMap::iterator pos;

    // this must exactly match the OS thread states in Thread.h
    const char *stateMapper[] = {   "Inactive",
                                    "Ready",
                                    "Running",
                                    "WaitingDelay",
                                    "WaitingInterval",
                                    "WaitingOr",
                                    "WaitingAnd",
                                    "WaitingSemaphore",
                                    "WaitingMailbox",
                                    "WaitingMutex",
                                    "Deleted"
                                };

    if ( threadTable.size() == 0 ) {
        printf("\r\nThere are currently no active control threads\r\n");
        return;
    }

    printf("\rControl Thread Table\n");
    for ( pos = threadTable.begin(); pos != threadTable.end(); ++pos ) {
        Thread *t = (Thread *)pos->second;
        printf("\r[%32s]->\tpri=%u\tstate=%s\tstack_size=%u\tfree=%u\tused=%u\tmax=%u\r\n",
               pos->first.c_str(),
               t->get_priority(),
               stateMapper[t->get_state()],
               t->stack_size(),
               t->free_stack(),
               t->used_stack(),
               t->max_stack());
    }
}