UART Command Parser Time Manager Data Store for SD Card for stm32l476 [it's not Licensed as BSD/GPLx]
Dependencies: mbed SDFileSystem
common/CommandParser.cpp@13:7cda5bef6390, 2019-05-27 (annotated)
- Committer:
- Inscape_ao
- Date:
- Mon May 27 03:07:42 2019 +0000
- Revision:
- 13:7cda5bef6390
- Parent:
- 7:9ab8809f9693
- Child:
- 19:36072b9b79f3
add uprintf(UART_printf); (this function can be disabled by uartOn=false)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Inscape_ao | 0:c347f602596d | 1 | #include "global.h" |
Inscape_ao | 0:c347f602596d | 2 | |
Inscape_ao | 2:a694440145e9 | 3 | /* UartLineHandler (start parsing) */ |
Inscape_ao | 0:c347f602596d | 4 | static void lineHandler(char *line) |
Inscape_ao | 0:c347f602596d | 5 | { |
Inscape_ao | 0:c347f602596d | 6 | pCP->parse(line); |
Inscape_ao | 0:c347f602596d | 7 | } |
Inscape_ao | 0:c347f602596d | 8 | |
Inscape_ao | 2:a694440145e9 | 9 | /* constructor */ |
Inscape_ao | 0:c347f602596d | 10 | CommandParser::CommandParser(UartReceiver *setUartReceiver, int setDeviceID, |
Inscape_ao | 0:c347f602596d | 11 | CmdParseRule *setRuleTable, int setRuleTableLen) |
Inscape_ao | 0:c347f602596d | 12 | { |
Inscape_ao | 0:c347f602596d | 13 | pR = setUartReceiver; |
Inscape_ao | 0:c347f602596d | 14 | pR->setLineHandler(lineHandler); |
Inscape_ao | 0:c347f602596d | 15 | deviceID = setDeviceID; |
Inscape_ao | 0:c347f602596d | 16 | ruleTable = setRuleTable; |
Inscape_ao | 0:c347f602596d | 17 | ruleTableLen = setRuleTableLen; |
Inscape_ao | 0:c347f602596d | 18 | pUart = pR->getCurrentUart(); |
Inscape_ao | 0:c347f602596d | 19 | } |
Inscape_ao | 0:c347f602596d | 20 | |
Inscape_ao | 2:a694440145e9 | 21 | /* start parsing */ |
Inscape_ao | 0:c347f602596d | 22 | void CommandParser::run(void) |
Inscape_ao | 0:c347f602596d | 23 | { |
Inscape_ao | 0:c347f602596d | 24 | pR->run(); |
Inscape_ao | 0:c347f602596d | 25 | } |
Inscape_ao | 0:c347f602596d | 26 | |
Inscape_ao | 2:a694440145e9 | 27 | /* process parsing */ |
Inscape_ao | 0:c347f602596d | 28 | int CommandParser::parse(char *pStr) |
Inscape_ao | 0:c347f602596d | 29 | { |
Inscape_ao | 0:c347f602596d | 30 | int rn; |
Inscape_ao | 0:c347f602596d | 31 | int len; |
Inscape_ao | 0:c347f602596d | 32 | char *head; |
Inscape_ao | 0:c347f602596d | 33 | /** skip - empty command*/ |
Inscape_ao | 0:c347f602596d | 34 | if (pStr[0] == '\0') { |
Inscape_ao | 13:7cda5bef6390 | 35 | uprintf("(empty)\n"); |
Inscape_ao | 0:c347f602596d | 36 | return 0; |
Inscape_ao | 0:c347f602596d | 37 | } |
Inscape_ao | 0:c347f602596d | 38 | /* protection for buffer overrun */ |
Inscape_ao | 0:c347f602596d | 39 | pStr[UartReceiver::MaxStr] = '\0'; |
Inscape_ao | 0:c347f602596d | 40 | len = strlen(pStr); |
Inscape_ao | 0:c347f602596d | 41 | |
Inscape_ao | 0:c347f602596d | 42 | /* parsing */ |
Inscape_ao | 0:c347f602596d | 43 | head = pStr; |
Inscape_ao | 13:7cda5bef6390 | 44 | uprintf("%s\n", pStr); |
Inscape_ao | 0:c347f602596d | 45 | |
Inscape_ao | 0:c347f602596d | 46 | /** Command Format ":0 CMD 0000" */ |
Inscape_ao | 0:c347f602596d | 47 | if (len != CmdLen) { |
Inscape_ao | 1:71c9c97c9f3d | 48 | this->reply(false, CommandParser::CmdReply::InvalidLen); |
Inscape_ao | 0:c347f602596d | 49 | return -1; |
Inscape_ao | 0:c347f602596d | 50 | } |
Inscape_ao | 0:c347f602596d | 51 | /** check Command Header */ |
Inscape_ao | 0:c347f602596d | 52 | if (head[0] != ':') { |
Inscape_ao | 1:71c9c97c9f3d | 53 | this->reply(false, CommandParser::CmdReply::InvalidFmt); |
Inscape_ao | 0:c347f602596d | 54 | return -1; |
Inscape_ao | 0:c347f602596d | 55 | } |
Inscape_ao | 0:c347f602596d | 56 | /** check Command DeviceID */ |
Inscape_ao | 0:c347f602596d | 57 | if ((head[1] - '0') != deviceID) { |
Inscape_ao | 0:c347f602596d | 58 | return 0; |
Inscape_ao | 0:c347f602596d | 59 | } |
Inscape_ao | 0:c347f602596d | 60 | |
Inscape_ao | 0:c347f602596d | 61 | /** search Command */ |
Inscape_ao | 0:c347f602596d | 62 | head += 3; |
Inscape_ao | 0:c347f602596d | 63 | for(rn = 0; rn < ruleTableLen; rn++) { |
Inscape_ao | 0:c347f602596d | 64 | int check; |
Inscape_ao | 0:c347f602596d | 65 | check = strncmp((const char*)(ruleTable[rn].cmdName), |
Inscape_ao | 0:c347f602596d | 66 | (const char*)(head),CmdNameLen); |
Inscape_ao | 0:c347f602596d | 67 | if (check != 0) { |
Inscape_ao | 0:c347f602596d | 68 | continue; |
Inscape_ao | 0:c347f602596d | 69 | } |
Inscape_ao | 0:c347f602596d | 70 | head += 4; |
Inscape_ao | 2:a694440145e9 | 71 | return (*ruleTable[rn].func)(this, head, |
Inscape_ao | 2:a694440145e9 | 72 | ruleTable[rn].exarg); |
Inscape_ao | 0:c347f602596d | 73 | |
Inscape_ao | 0:c347f602596d | 74 | } |
Inscape_ao | 1:71c9c97c9f3d | 75 | this->reply(false, CommandParser::CmdReply::InvalidCmd); |
Inscape_ao | 0:c347f602596d | 76 | return -1; |
Inscape_ao | 1:71c9c97c9f3d | 77 | } |
Inscape_ao | 1:71c9c97c9f3d | 78 | |
Inscape_ao | 2:a694440145e9 | 79 | /* get my Device ID */ |
Inscape_ao | 1:71c9c97c9f3d | 80 | int CommandParser::getDeviceID(void) |
Inscape_ao | 1:71c9c97c9f3d | 81 | { |
Inscape_ao | 1:71c9c97c9f3d | 82 | return deviceID; |
Inscape_ao | 1:71c9c97c9f3d | 83 | } |
Inscape_ao | 1:71c9c97c9f3d | 84 | |
Inscape_ao | 2:a694440145e9 | 85 | /* generate ACK/NAK with int code */ |
Inscape_ao | 1:71c9c97c9f3d | 86 | void CommandParser::reply(bool ack, int replyCode) |
Inscape_ao | 1:71c9c97c9f3d | 87 | { |
Inscape_ao | 1:71c9c97c9f3d | 88 | char replyStr[] = "0000"; |
Inscape_ao | 1:71c9c97c9f3d | 89 | sprintf(replyStr, "%04d", replyCode); |
Inscape_ao | 1:71c9c97c9f3d | 90 | this->reply(ack, replyStr); |
Inscape_ao | 1:71c9c97c9f3d | 91 | } |
Inscape_ao | 1:71c9c97c9f3d | 92 | |
Inscape_ao | 2:a694440145e9 | 93 | /* generate ACK/NAK with String */ |
Inscape_ao | 1:71c9c97c9f3d | 94 | void CommandParser::reply(bool ack, char* replyStr) |
Inscape_ao | 1:71c9c97c9f3d | 95 | { |
Inscape_ao | 7:9ab8809f9693 | 96 | const char CmdReplyStrDefault[] = ":0 ACK 0004 0000\n"; |
Inscape_ao | 1:71c9c97c9f3d | 97 | const int CmdReplyLen = sizeof(CmdReplyStrDefault) /* include \0 */; |
Inscape_ao | 1:71c9c97c9f3d | 98 | const int CmdReplyDevPos = 1; |
Inscape_ao | 1:71c9c97c9f3d | 99 | const int CmdReplyAckPos = 3; |
Inscape_ao | 7:9ab8809f9693 | 100 | const int CmdReplyCodePos = 12; |
Inscape_ao | 7:9ab8809f9693 | 101 | const int CmdReplyEndPos = 16; |
Inscape_ao | 1:71c9c97c9f3d | 102 | |
Inscape_ao | 1:71c9c97c9f3d | 103 | char str[CmdReplyLen]; |
Inscape_ao | 1:71c9c97c9f3d | 104 | |
Inscape_ao | 1:71c9c97c9f3d | 105 | /* set default handler */ |
Inscape_ao | 1:71c9c97c9f3d | 106 | memcpy(str, CmdReplyStrDefault, CmdReplyLen); |
Inscape_ao | 1:71c9c97c9f3d | 107 | str[CmdReplyDevPos] = '0' + getDeviceID(); |
Inscape_ao | 1:71c9c97c9f3d | 108 | if (!ack) { |
Inscape_ao | 1:71c9c97c9f3d | 109 | memcpy(&str[CmdReplyAckPos], "NAK", 3); |
Inscape_ao | 1:71c9c97c9f3d | 110 | } |
Inscape_ao | 1:71c9c97c9f3d | 111 | memcpy(&str[CmdReplyCodePos], replyStr, 4); |
Inscape_ao | 1:71c9c97c9f3d | 112 | str[CmdReplyEndPos] = '\n'; |
Inscape_ao | 13:7cda5bef6390 | 113 | uprintf(str); |
Inscape_ao | 2:a694440145e9 | 114 | } |
Inscape_ao | 2:a694440145e9 | 115 | |
Inscape_ao | 2:a694440145e9 | 116 | /* get currentUart */ |
Inscape_ao | 2:a694440145e9 | 117 | Serial *CommandParser::getCurrentUart(void) |
Inscape_ao | 2:a694440145e9 | 118 | { |
Inscape_ao | 2:a694440145e9 | 119 | return pUart; |
Inscape_ao | 0:c347f602596d | 120 | } |