📄 ext_serial_pkt.c
字号:
if(numAct!=numExp) {
abort_LED(17);
error=EXT_ERROR;
goto EXIT_POINT;
}
EXIT_POINT:PRINT_DEBUG_MSG_LVL4("OUT, error status: ");
PRINT_DEBUG_MSG_LVL4_UDec(error);
PRINT_DEBUG_MSG_NL4;
return error;
} /* end SetExtSerialPacket */
/* Function: GetExtSerialPacket ================================================
* Abstract:
* Examines incoming bytes for a packet header and discards any chars that do
* not fit into a packet header. After receiving a packet header, records
* incoming bytes into a packet buffer until a packet tail is read. Compares
* incoming bytes with the escape character and handles any escaped chars
* appropriately (escape char is discarded and next char is exclusive or'd
* with the mask character).
*
* EXT_NO_ERROR is returned on success, EXT_ERROR on failure.
*/
PUBLIC boolean_T GetExtSerialPacket(ExtSerialPacket *pkt, ExtSerialPort *portDev) {
char char1=0;
uint32_T numCharRecvd=0;
boolean_T doFilter=false;
boolean_T PacketError=false;
boolean_T error=EXT_NO_ERROR;
// local function name... debugging only
#if DEBUG_MSG_LVL > 0
const char *funct_name="GetExtSerialPacket";
#endif
PRINT_DEBUG_MSG_LVL4("IN");
PRINT_DEBUG_MSG_NL4;
/* If not connected, return immediately. */
if(!portDev->fConnected) {
abort_LED(18);
return EXT_ERROR;
}
/* Initialize some fileds of the packet. */
pkt->head[0]=packet_head;
pkt->head[1]=packet_head;
pkt->tail[0]=packet_tail;
pkt->tail[1]=packet_tail;
pkt->state=ESP_NoPacket;
pkt->cursor=0;
pkt->DataCount=0;
pkt->inQuote=false;
PRINT_DEBUG_MSG_LVL4("State -> ESP_NoPacket");
PRINT_DEBUG_MSG_NL4;
while(1) {
/* Get a character from input stream. */
error=ExtSerialPortGetRawChar(portDev, &char1, &numCharRecvd);
if(error!=EXT_NO_ERROR) {
PRINT_DEBUG_MSG_LVL4("Error... in call to ExtSerialPortGetRawChar\n\r");
/* never happens, errors caught above -- fw-07-07 */
abort_LED(19); // just in case
goto EXIT_POINT;
}
if(numCharRecvd!=1) {
// debug - indicate errors
#ifndef MATLAB_MEX_FILE
blinky(10000);
#endif
pkt->state=ESP_NoPacket;
pkt->cursor=0;
PRINT_DEBUG_MSG_LVL4("Error... numCharRecvd is not '1' but ");
PRINT_DEBUG_MSG_LVL4_UDec(numCharRecvd);
PRINT_DEBUG_MSG_NL4;
abort_LED(20);
error=EXT_ERROR;
goto EXIT_POINT;
}
/* Handle quoting and filtering (does not deal with xon/xoff issues). */
switch(pkt->state) {
case ESP_InType:
case ESP_InSize:
case ESP_InPayload:
/* Handle quoted characters in payload. */
if(pkt->inQuote) {
pkt->inQuote=false;
char1^= mask_character;
}
else {
/*
* No characters requiring escaping should be in the input
* stream, except for control purposes.
*/
switch(char1) {
case escape_character:
//PRINT_DEBUG_MSG_LVL1_Raw("*\n\r");
pkt->inQuote=true;
/* Need to go get next charater at this point. */
continue;
break;
/*
* other special characters should only exist
* in payload when quoted.
*/
case packet_head:
/*
* Error - start handling the packet this header
* goes with.
*/
PRINT_DEBUG_MSG_LVL1("Error. received unexpected packet_head... restarting.\n\r");
pkt->cursor=(char*)&pkt->head;
*pkt->cursor++=char1;
pkt->DataCount++;
pkt->state=ESP_InHead;
continue;
case packet_tail:
/* Error - reset packet handling. */
PRINT_DEBUG_MSG_LVL1("Error. received unexpected packet_tail.\n\r");
pkt->cursor=0;
pkt->state=ESP_NoPacket;
PacketError=false;
break;
default:
break;
}
}
break;
/* No quoting in non-payload portions. */
case ESP_NoPacket:
case ESP_InHead:
case ESP_InTail:
case ESP_Complete:
default:
break;
}
#ifdef ERASE
PRINT_DEBUG_MSG_LVL1_Raw("0x");
PRINT_DEBUG_MSG_LVL1_UHex((uint16_T)char1);
PRINT_DEBUG_MSG_LVL1_Raw("\n\r");
#endif
switch(pkt->state) {
case ESP_NoPacket:
PRINT_DEBUG_MSG_LVL4("State -> ESP_NoPacket");
PRINT_DEBUG_MSG_NL4;
if(char1==packet_head) {
/*
* When a byte matches a packet header tag byte,
* save it and change state.
*/
pkt->cursor=(char*)&pkt->head;
*pkt->cursor++=char1;
pkt->DataCount++;
pkt->state=ESP_InHead;
}
break;
case ESP_InHead:
PRINT_DEBUG_MSG_LVL4("State -> ESP_InHead");
PRINT_DEBUG_MSG_NL4;
if(char1==packet_head) {
/*
* In this state, the only acceptable input is a packet header
* tag byte which will cause packet processing to progress to
* the next state.
*/
*pkt->cursor++=char1;
pkt->DataCount=0;
pkt->state=ESP_InType;
pkt->cursor=(char*)&pkt->PacketType;
}
else {
PacketError=true;
}
break;
case ESP_InType:
PRINT_DEBUG_MSG_LVL4("State -> ESP_InType");
#if DEBUG_MSG_LVL >= 4
if(char1==UNDEFINED_PACKET) {
PRINT_DEBUG_MSG_LVL4_Raw(" (UNDEFINED_PACKET)");
}
if(char1==EXTMODE_PACKET) {
PRINT_DEBUG_MSG_LVL4_Raw(" (EXTMODE_PACKET)");
}
if(char1==ACK_PACKET) {
PRINT_DEBUG_MSG_LVL4_Raw(" (ACK_PACKET)");
}
#endif
PRINT_DEBUG_MSG_NL4;
if(pkt->DataCount<sizeof(pkt->PacketType)) {
/*
* In this state, the byte count determines where this
* state stands.
*/
*pkt->cursor++=char1;
pkt->DataCount++;
if(pkt->DataCount==sizeof(pkt->PacketType)) {
pkt->state=ESP_InSize;
pkt->cursor=(char*)&pkt->size;
pkt->DataCount=0;
}
}
else {
PacketError=true;
}
break;
case ESP_InSize:
PRINT_DEBUG_MSG_LVL4("State -> ESP_InSize");
PRINT_DEBUG_MSG_NL4;
if(pkt->DataCount<sizeof(pkt->size)) {
/*
* In this state, the byte count determines where this
* state stands.
*/
*pkt->cursor++=char1;
pkt->DataCount++;
if(pkt->DataCount==sizeof(pkt->size)) {
pkt->size=String2Num((char*)&pkt->size, portDev->isLittleEndian);
PRINT_DEBUG_MSG_LVL5("Number of data bytes in message: ");
PRINT_DEBUG_MSG_LVL5_UDec((uint_T)pkt->size);
PRINT_DEBUG_MSG_NL5;
pkt->DataCount=0;
if(pkt->size!=0) {
pkt->state=ESP_InPayload;
pkt->cursor=(char*)pkt->Buffer;
}
else {
pkt->state=ESP_InTail;
pkt->cursor=(char*)&pkt->tail;
}
}
}
else {
PacketError=true;
}
break;
case ESP_InPayload:
if(pkt->DataCount<pkt->size) {
/*
* In this state, the byte count determines where this
* state stands.
*/
*pkt->cursor++=char1;
pkt->DataCount++;
PRINT_DEBUG_MSG_LVL4("State -> ESP_InPayload [");
PRINT_DEBUG_MSG_LVL4_UDec(pkt->DataCount);
PRINT_DEBUG_MSG_LVL4_Raw("/");
PRINT_DEBUG_MSG_LVL4_UDec(pkt->size);
PRINT_DEBUG_MSG_LVL4_Raw("]: 0x");
PRINT_DEBUG_MSG_LVL4_UHex((uint8_T)char1);
PRINT_DEBUG_MSG_NL4;
if(pkt->DataCount==pkt->size) {
pkt->state=ESP_InTail;
pkt->cursor=(char*)&pkt->tail;
pkt->DataCount=0;
}
}
else {
PacketError=true;
}
break;
case ESP_InTail:
PRINT_DEBUG_MSG_LVL4("State -> ESP_InTail");
PRINT_DEBUG_MSG_NL4;
if(pkt->DataCount<sizeof(pkt->tail)) {
if(char1==packet_tail) {
/*
* In this state, the only acceptable input is a packet
* tail tag byte.
*/
*pkt->cursor++=char1;
pkt->DataCount++;
if(pkt->DataCount==sizeof(pkt->tail)) {
pkt->state=ESP_Complete;
pkt->cursor=NULL;
pkt->DataCount=0;
if(pkt->state!=ESP_Complete) {
PRINT_DEBUG_MSG_LVL4("Error... pkt->state not 'ESP_Complete'\n\r");
abort_LED(21);
error=EXT_ERROR;
}
goto EXIT_POINT;
}
}
else {
PacketError=true;
}
}
else {
PacketError=true;
}
break;
case ESP_Complete:
PRINT_DEBUG_MSG_LVL4("State -> ESP_Complete");
PRINT_DEBUG_MSG_NL4;
break;
default:
break;
}
if(PacketError) {
PRINT_DEBUG_MSG_LVL4("Packet error. New state -> ESP_NoPacket");
PRINT_DEBUG_MSG_NL4;
pkt->cursor=0;
pkt->state=ESP_NoPacket;
PacketError=false;
}
} /* end-of-while */
EXIT_POINT:PRINT_DEBUG_MSG_LVL4("OUT, error status: ");
PRINT_DEBUG_MSG_LVL4_UDec(error);
PRINT_DEBUG_MSG_NL4;
return error;
} /* end GetExtSerialPacket */
/* [EOF] ext_serial_pkt.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -