xrocusOS_ADXL355 version

Dependencies:   mbed SDFileSystem

common/CommandParser.cpp

Committer:
APS_Lab
Date:
16 months ago
Revision:
20:2f2687580ecb
Parent:
19:36072b9b79f3

File content as of revision 20:2f2687580ecb:

#include "global.h"

/* UartLineHandler (start parsing) */
static void lineHandler(char *line)
{
    pCP->parse(line);
}

/* constructor */
CommandParser::CommandParser(UartReceiver *setUartReceiver, int setDeviceID,
    CmdParseRule *setRuleTable, int setRuleTableLen)
{
    pR = setUartReceiver;
    pR->setLineHandler(lineHandler);
    deviceID = setDeviceID;
    ruleTable = setRuleTable;
    ruleTableLen = setRuleTableLen;
    pUart = pR->getCurrentUart();
}

/* start parsing */
void CommandParser::run(void)
{
    pR->run();
}

/* process parsing */
int CommandParser::parse(char *pStr)
{
    int rn;
    int len;
    char *head;
    /** skip - empty command*/
    if (pStr[0] == '\0') {
        uprintf("(empty)\n");
        return 0;
    }
    /* protection for buffer overrun */
    pStr[UartReceiver::MaxStr] = '\0';
    len = strlen(pStr);
    
    /* parsing */
    head = pStr;
    //uprintf("%s\n", pStr);
    
    /** Command Format ":0 CMD 0000" */
    if (len != CmdLen) {
        this->reply(false, CommandParser::NakCode::NAK_INVAL_LEN);
        return -1;
    }
    /** check Command Header */
    if (head[0] != ':') {
        this->reply(false, CommandParser::NakCode::NAK_INVAL_FMT);
        return -1;
    }
    /** check Command DeviceID */
    if ((head[1] - '0') != deviceID) {
        return 0;
    }
    
    /** search Command */
    head += 3;
    for(rn = 0; rn < ruleTableLen; rn++) {
        int check;
        check = strncmp((const char*)(ruleTable[rn].cmdName), 
            (const char*)(head),CmdNameLen);
        if (check != 0) {
            continue;
        }
        head += 4;
        return (*ruleTable[rn].func)(this, head,
            ruleTable[rn].exarg);

    }
    this->reply(false, CommandParser::NakCode::NAK_INVAL_CMD);
    return -1;
}

/* get my Device ID */
int CommandParser::getDeviceID(void)
{
    return deviceID;
}

/* generate ACK/NAK with int code */
void CommandParser::reply(bool ack, int replyCode)
{
    char replyStr[] = "0000";
    sprintf(replyStr, "%04d", replyCode);
    this->reply(ack, replyStr);
}

/* generate ACK/NAK with String */
void CommandParser::reply(bool ack, char* replyStr)
{
    const char CmdReplyStrDefault[] = ":0 ACK 0004 0000\n";
    const int CmdReplyLen = sizeof(CmdReplyStrDefault) /* include \0 */;
    const int CmdReplyDevPos = 1;
    const int CmdReplyAckPos = 3;
    const int CmdReplyCodePos = 12;
    const int CmdReplyEndPos = 16;
    
    char str[CmdReplyLen];
    
    /* set default handler */
    memcpy(str, CmdReplyStrDefault, CmdReplyLen);
    str[CmdReplyDevPos] = '0' + getDeviceID();
    if (!ack) {
        memcpy(&str[CmdReplyAckPos], "NAK", 3);
    }
    memcpy(&str[CmdReplyCodePos], replyStr, 4);
    str[CmdReplyEndPos] = '\n';
    uprintf(str);
}

/* get currentUart */
Serial *CommandParser::getCurrentUart(void)
{
    return pUart;
}