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@7:9ab8809f9693, 2019-05-11 (annotated)
- Committer:
- Inscape_ao
- Date:
- Sat May 11 04:03:33 2019 +0000
- Revision:
- 7:9ab8809f9693
- Parent:
- 2:a694440145e9
- Child:
- 13:7cda5bef6390
add Repeatable Controllor; add Dummy Devicedriver; add Sensing Control Command; (All Host->Device Commands are already implemented)
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 | 2:a694440145e9 | 35 | pUart->printf("(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 | 2:a694440145e9 | 44 | pUart->printf("%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 | //pUart->printf("[CommandParser::parse] Invalid Command Length\n"); |
Inscape_ao | 1:71c9c97c9f3d | 49 | this->reply(false, CommandParser::CmdReply::InvalidLen); |
Inscape_ao | 0:c347f602596d | 50 | return -1; |
Inscape_ao | 0:c347f602596d | 51 | } |
Inscape_ao | 0:c347f602596d | 52 | /** check Command Header */ |
Inscape_ao | 0:c347f602596d | 53 | if (head[0] != ':') { |
Inscape_ao | 1:71c9c97c9f3d | 54 | //pUart->printf("[CommandParser::parse] Invalid Format\n"); |
Inscape_ao | 1:71c9c97c9f3d | 55 | this->reply(false, CommandParser::CmdReply::InvalidFmt); |
Inscape_ao | 0:c347f602596d | 56 | return -1; |
Inscape_ao | 0:c347f602596d | 57 | } |
Inscape_ao | 0:c347f602596d | 58 | /** check Command DeviceID */ |
Inscape_ao | 0:c347f602596d | 59 | if ((head[1] - '0') != deviceID) { |
Inscape_ao | 1:71c9c97c9f3d | 60 | //pUart->printf("[CommandParser::parse] Ignore (DST is other)\n"); |
Inscape_ao | 0:c347f602596d | 61 | return 0; |
Inscape_ao | 0:c347f602596d | 62 | } |
Inscape_ao | 0:c347f602596d | 63 | |
Inscape_ao | 0:c347f602596d | 64 | /** search Command */ |
Inscape_ao | 0:c347f602596d | 65 | head += 3; |
Inscape_ao | 0:c347f602596d | 66 | for(rn = 0; rn < ruleTableLen; rn++) { |
Inscape_ao | 0:c347f602596d | 67 | int check; |
Inscape_ao | 0:c347f602596d | 68 | check = strncmp((const char*)(ruleTable[rn].cmdName), |
Inscape_ao | 0:c347f602596d | 69 | (const char*)(head),CmdNameLen); |
Inscape_ao | 0:c347f602596d | 70 | if (check != 0) { |
Inscape_ao | 0:c347f602596d | 71 | continue; |
Inscape_ao | 0:c347f602596d | 72 | } |
Inscape_ao | 0:c347f602596d | 73 | head += 4; |
Inscape_ao | 2:a694440145e9 | 74 | return (*ruleTable[rn].func)(this, head, |
Inscape_ao | 2:a694440145e9 | 75 | ruleTable[rn].exarg); |
Inscape_ao | 0:c347f602596d | 76 | |
Inscape_ao | 0:c347f602596d | 77 | } |
Inscape_ao | 1:71c9c97c9f3d | 78 | //pUart->printf("[CommandParser::parse] Invalid Command"); |
Inscape_ao | 1:71c9c97c9f3d | 79 | this->reply(false, CommandParser::CmdReply::InvalidCmd); |
Inscape_ao | 0:c347f602596d | 80 | return -1; |
Inscape_ao | 1:71c9c97c9f3d | 81 | } |
Inscape_ao | 1:71c9c97c9f3d | 82 | |
Inscape_ao | 2:a694440145e9 | 83 | /* get my Device ID */ |
Inscape_ao | 1:71c9c97c9f3d | 84 | int CommandParser::getDeviceID(void) |
Inscape_ao | 1:71c9c97c9f3d | 85 | { |
Inscape_ao | 1:71c9c97c9f3d | 86 | return deviceID; |
Inscape_ao | 1:71c9c97c9f3d | 87 | } |
Inscape_ao | 1:71c9c97c9f3d | 88 | |
Inscape_ao | 2:a694440145e9 | 89 | /* generate ACK/NAK with int code */ |
Inscape_ao | 1:71c9c97c9f3d | 90 | void CommandParser::reply(bool ack, int replyCode) |
Inscape_ao | 1:71c9c97c9f3d | 91 | { |
Inscape_ao | 1:71c9c97c9f3d | 92 | char replyStr[] = "0000"; |
Inscape_ao | 1:71c9c97c9f3d | 93 | sprintf(replyStr, "%04d", replyCode); |
Inscape_ao | 1:71c9c97c9f3d | 94 | this->reply(ack, replyStr); |
Inscape_ao | 1:71c9c97c9f3d | 95 | } |
Inscape_ao | 1:71c9c97c9f3d | 96 | |
Inscape_ao | 2:a694440145e9 | 97 | /* generate ACK/NAK with String */ |
Inscape_ao | 1:71c9c97c9f3d | 98 | void CommandParser::reply(bool ack, char* replyStr) |
Inscape_ao | 1:71c9c97c9f3d | 99 | { |
Inscape_ao | 7:9ab8809f9693 | 100 | const char CmdReplyStrDefault[] = ":0 ACK 0004 0000\n"; |
Inscape_ao | 1:71c9c97c9f3d | 101 | const int CmdReplyLen = sizeof(CmdReplyStrDefault) /* include \0 */; |
Inscape_ao | 1:71c9c97c9f3d | 102 | const int CmdReplyDevPos = 1; |
Inscape_ao | 1:71c9c97c9f3d | 103 | const int CmdReplyAckPos = 3; |
Inscape_ao | 7:9ab8809f9693 | 104 | const int CmdReplyCodePos = 12; |
Inscape_ao | 7:9ab8809f9693 | 105 | const int CmdReplyEndPos = 16; |
Inscape_ao | 1:71c9c97c9f3d | 106 | |
Inscape_ao | 1:71c9c97c9f3d | 107 | char str[CmdReplyLen]; |
Inscape_ao | 1:71c9c97c9f3d | 108 | |
Inscape_ao | 1:71c9c97c9f3d | 109 | /* set default handler */ |
Inscape_ao | 1:71c9c97c9f3d | 110 | memcpy(str, CmdReplyStrDefault, CmdReplyLen); |
Inscape_ao | 1:71c9c97c9f3d | 111 | str[CmdReplyDevPos] = '0' + getDeviceID(); |
Inscape_ao | 1:71c9c97c9f3d | 112 | if (!ack) { |
Inscape_ao | 1:71c9c97c9f3d | 113 | memcpy(&str[CmdReplyAckPos], "NAK", 3); |
Inscape_ao | 1:71c9c97c9f3d | 114 | } |
Inscape_ao | 1:71c9c97c9f3d | 115 | memcpy(&str[CmdReplyCodePos], replyStr, 4); |
Inscape_ao | 1:71c9c97c9f3d | 116 | str[CmdReplyEndPos] = '\n'; |
Inscape_ao | 1:71c9c97c9f3d | 117 | pUart->printf(str); |
Inscape_ao | 2:a694440145e9 | 118 | } |
Inscape_ao | 2:a694440145e9 | 119 | |
Inscape_ao | 2:a694440145e9 | 120 | /* get currentUart */ |
Inscape_ao | 2:a694440145e9 | 121 | Serial *CommandParser::getCurrentUart(void) |
Inscape_ao | 2:a694440145e9 | 122 | { |
Inscape_ao | 2:a694440145e9 | 123 | return pUart; |
Inscape_ao | 0:c347f602596d | 124 | } |