user-0 提问: 剥离传过来的两层协议（分二个包发过来）要求：获取第二层协议的数据内容

回复:
user: user-0
content: #include "queue.h" #include "string.h" #include "stdio.h" #include <stdlib.h> QUEUE gstSpQueue; // SP协议 QUEUE gstTpQueue; // 8583协议 TERPACK gstTp; enum { 	SP_STATUS_STX		= 0, 	SP_STATUS_FRAME, 	SP_STATUS_TOTLEN, 	SP_STATUS_TYPE, 	SP_STATUS_CMD, 	SP_STATUS_RETCODE, 	SP_STATUS_DATALEN, 	SP_STATUS_DATA, 	SP_STATUS_CHECKCODE, 	SP_STATUS_ETX, };  enum { 	TP_STATUS_LEN1 =0, 	TP_STATUS_LEN2, 	TP_STATUS_DATA, };    void ClearQueue(QUEUE *Queue) { 	Queue->Head = 0; 	Queue->Tail = 0; 	memset(Queue->Data,0,sizeof(Queue->Data)); }  int IsQueueEmpty(QUEUE *Queue) {     if(Queue->Head == Queue->Tail) {        	return TRUE;     }         else {        	return FALSE;         }	     }  int IsQueueFull(QUEUE *Queue) { 	if(Queue->Head == ((Queue->Tail+1) % QUEUE_SIZE)) {        	return TRUE;     }         else {        	return FALSE;         }	     }  int DelQueue(QUEUE *Queue) { 	if (TRUE == IsQueueEmpty(Queue)){ 		return FALSE; 	}     else { 		//Queue->Data[Queue->Head]= 0; 		Queue->Head = ((Queue->Head+1) % QUEUE_SIZE);        	return TRUE;         }	     }  int InsertQueue(QUEUE *Queue,unsigned char *lpIn,int nLen) { 	int i;  	for(i = 0; i < nLen; i++) { 	    if( !IsQueueFull(Queue) ) { 	    	Queue->Data[Queue->Tail] = lpIn[i]; 	   		Queue->Tail = (Queue->Tail + 1) % QUEUE_SIZE; 	    } 	    else { 			ClearQueue(Queue); 			Queue->Data[Queue->Tail] = lpIn[i]; 	   		Queue->Tail = (Queue->Tail + 1) % QUEUE_SIZE; 	        //break; 	    } 	}	     	return i; }  void SetQueueHead(QUEUE *Queue,int nHead) { 	nHead = nHead % QUEUE_SIZE; 	if( !IsQueueEmpty(Queue) ) { 		if(Queue->Head < Queue->Tail) { 			if(nHead >= Queue->Head &&  nHead <= Queue->Tail) { 				Queue->Head = nHead; 			} 			else { 				ClearQueue(Queue); 			} 		} 		else { 			if(nHead >= Queue->Head || nHead <= Queue->Tail) { 				Queue->Head = nHead; 			}	 			else { 				ClearQueue(Queue); 			} 		}	 	} }  int GetQueueHead(QUEUE *Queue) { 	return Queue->Head; }  int TryQueueData(QUEUE *Queue,int nHead,unsigned char *lpOut) { 	nHead = nHead % QUEUE_SIZE; 	if( !IsQueueEmpty(Queue) ) { 		if(Queue->Head < Queue->Tail) { 			if(nHead >= Queue->Head &&  nHead < Queue->Tail) { 				*lpOut = Queue->Data[nHead]; 				DelQueue(Queue);//出队列 从队列头删除, 				return TRUE; 			} 		} 		else { 			if(nHead >= Queue->Head || nHead < Queue->Tail) { 				*lpOut = Queue->Data[nHead]; 				DelQueue(Queue);////出队列 从队列头删除 				return TRUE; 			}	 		} 	} 	return FALSE; }  int ParseSpData(unsigned char *out_buf, unsigned int *out_len) {    unsigned char Data = 0,CheckSum = 0,ParseStep = 0;                        			     int head, Result_len = 0, DataNum = 0,ret = 0;    int iLen = 0;    int isoNum = 0;    unsigned char *Result_buf = (unsigned char *)malloc(QUEUE_SIZE);    memset(Result_buf,0, QUEUE_SIZE);        head = gstSpQueue.Head;	    while( TryQueueData(&gstSpQueue,head,&Data) ) {	         head = (head + 1) % QUEUE_SIZE;						 		switch( ParseStep )	{             case SP_STATUS_STX:                 if(Data == STX)	{                     ParseStep = SP_STATUS_FRAME;					                     CheckSum = 0; 					DataNum = 0; 					iLen = 0; 					isoNum = 0;                     Result_len = 0;	                 }                 else{                     SetQueueHead(&gstTpQueue,head); 	                 }                 break;             case SP_STATUS_FRAME:                              				ParseStep = SP_STATUS_TOTLEN;                 break;             case SP_STATUS_TOTLEN:  				CheckSum ^= Data; 				if(0 == DataNum) { 					DataNum++; 					iLen =  Data<<8; 				} else { 					iLen += Data; 					DataNum = 0; 					ParseStep = SP_STATUS_TYPE; 				} 				break;		 			case SP_STATUS_TYPE: 				CheckSum ^= Data; 				ParseStep = SP_STATUS_CMD; 				break;             case SP_STATUS_CMD:	  				CheckSum ^= Data; 				ParseStep = SP_STATUS_RETCODE; 				break; 			case SP_STATUS_RETCODE: 				CheckSum ^= Data; 				ParseStep = SP_STATUS_DATALEN; 				break; 			case SP_STATUS_DATALEN: 				if(0 == isoNum) { 					isoNum++; 					Result_len =  Data<<8; 				} else { 					Result_len += Data; 					isoNum = 0; 					if(0 == Result_len) { 						SetQueueHead(&gstSpQueue,head); 						ParseStep = SP_STATUS_STX;     // 8583报文长度=0,就从头再来。 						break; 					}else { 						ParseStep = SP_STATUS_DATA; 					} 				} 				CheckSum ^= Data; 				break; 			case SP_STATUS_DATA: 				Result_buf[isoNum ++] = Data; 				CheckSum ^= Data; 				if(isoNum == 3){ 					printf("\n"); 				} 				if(isoNum == Result_len ) { 					ParseStep = SP_STATUS_CHECKCODE;               				}  				break; 			case SP_STATUS_CHECKCODE: 				if(Data == CheckSum){ 					ParseStep = SP_STATUS_ETX;  				} else { 					SetQueueHead(&gstSpQueue,head);  				} 				break; 			case SP_STATUS_ETX: 				if(0x40 == Data) { 					ParseStep = SP_STATUS_STX;  					InsertQueue(&gstTpQueue, Result_buf, Result_len); 					if(TRUE == ParseTpData(out_buf,out_len)) { 						ret = TRUE; 						goto exit; 					} 				} else { 					SetQueueHead(&gstSpQueue,head);  				} 				break;             default:             	break;     	} 	    	}  exit:    printf("ret  =%d,out_len =%d\n",ret,*out_len);    if(NULL !=Result_buf) 		free(Result_buf);    return ret; }   int ParseTpData(unsigned char *out_buf, unsigned int *out_len) {    unsigned char Data = 0;                        			     int head, Result_len = 0;    int isoNum = 0,ret = 0;    head = gstTpQueue.Head;	    while( TryQueueData(&gstTpQueue,head,&Data) ) {	         head = (head + 1) % QUEUE_SIZE;						 		switch( gstTp.status )	{	 			case TP_STATUS_LEN1: 					gstTp.Data[gstTp.ipos++] = Data<<8; 					gstTp.status = TP_STATUS_LEN2; 					 					break; 			case TP_STATUS_LEN2: 					gstTp.Data[gstTp.ipos++] = Data; 					gstTp.status = TP_STATUS_DATA; 					 					break; 			case TP_STATUS_DATA: 					gstTp.Data[gstTp.ipos++] = Data; 					if( gstTp.ipos  == (gstTp.Data[0]*256 + gstTp.Data[1]) +2 ) { // ipos增加了 datalen[0]+datalen[1] 						*out_len = gstTp.ipos; 						memcpy(out_buf, gstTp.Data, gstTp.ipos); 						gstTp.status = TP_STATUS_LEN1; 						ret = TRUE; 						goto exit;         					}  				break;             default:             	break;     	} 	 	}  exit:    //printf("ret  =%d,8583_len =%d\n",ret,gstTp.ipos);    return ret; }  main.c #include "stdio.h" #include "queue.h" void main() { 	int iRet =-1,i; 	unsigned int iLen = 0; 	unsigned char buffer[1024]={0}, sResultBuff[QUEUE_SIZE] = {0}; 	 	/* 	unsigned char test[]={0x02,0x00,0x00,0x05,0x6C,0x06,0x00,0x00,0x00,0x6F,0x40 };     unsigned char test1[]={0x02,0x00,0x00,0x07,0x6C,0x06,0x00,0x00,0x02,0x00,0x08,0x67,0x40};     unsigned char test2[]={0x02,0x00,0x00,0x0D,0x6C,0x06,0x00,0x00,0x08,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 	   0x08,0x67,0x40};  	InsertQueue(&gstSpQueue, test, sizeof(test)); 	InsertQueue(&gstSpQueue, test1, sizeof(test1)); 	InsertQueue(&gstSpQueue, test2, sizeof(test2)); 	*/ 		 	 	 unsigned char test[]={       0x02,0x00,0x00,0xF7,0xA1,0x12,0x00, 0x00,0xF2,0x00,0xF2,0x60,0x00,0x00,0x09,0x51, 0x90,0x20,0x01,0x00,0x00,0x00,0x39,0x39, 0x30,0x36,0x30,0x35,0x30,0x35,0x35,0x33, 0x33,0x36,0x30,0x30,0x30,0x30,0x30,0x30, 0x30,0x30,0x30,0x31,0x31,0x33,0x30,0x30, 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30, 0x30,0x30,0x30,0x33,0x30,0x30,0x30,0x30, 0x30,0x30,0x30,0x30,0x39,0x39,0x30,0x36, 0x30,0x35,0x30,0x35,0x35,0x33,0x33,0x36, 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30, 0x30,0x30,0x30,0x08,0x10,0x00,0x38,0x00, 0x01,0x02,0xC0,0x00,0x14,0x00,0x00,0x02, 0x08,0x43,0x15,0x03,0x30,0x08,0x99,0x99, 0x00,0x01,0x30,0x30,0x30,0x30,0x30,0x30, 0x30,0x30,0x31,0x31,0x39,0x39,0x30,0x36, 0x30,0x35,0x30,0x35,0x35,0x33,0x33,0x36, 0x30,0x30,0x30,0x00,0x11,0x50,0x00,0x00, 0x81,0x00,0x30,0x01,0x04,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x7C,0x4F,0x92,0x62,0x76,0x2C,0xB7, 0xFE,0xC7,0xB9,0x32,0x4D,0x5D,0x42,0x8F, 0xE6,0x85,0x97,0x16,0xE1,0xAC,0x66,0x1E, 0x60,0xBC,0x6C,0x9C,0xFE,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0xA6,0x6D,0xF6, 0xD8,0x43,0xCE,0x13,0x56,0xF7,0xC2,0xBD, 0x59,0x4F,0xEB,0x88,0xD5,0xDE,0x98,0x46, 0x4F,0x7C,0x3D,0xE3,0x40     }; 	     unsigned char test4[]={0x02,0x00,0x00,0x07,0x6A,0x01,0x00,0x00,         0x02,0xB2,0xDA,0x06,0x40 }; 	     InsertQueue(&gstSpQueue, test, sizeof(test));     InsertQueue(&gstSpQueue, test4, sizeof(test4));  	iRet = ParseSpData(sResultBuff, &iLen); 	 	for( i =0;i<iLen;i++) printf("%02x",sResultBuff[i]); 	printf("\n"); 	 	return; }  queue.h #ifndef _QUEUE_H #define _QUEUE_H  #define QUEUE_SIZE		(2*1024)								//队列长度 #define STX				0x02									//头 #define ETX				0x03									//结束标志  #ifndef TRUE  #define TRUE	1 #endif  #ifndef FALSE	 #define FALSE	0 #endif  typedef struct _QUEUE														 { 	int Head; 	int Tail; 	unsigned char  Data[QUEUE_SIZE]; }QUEUE;   typedef struct _tp{ 	unsigned int status; 	unsigned char ipos; 	unsigned char Data[QUEUE_SIZE]; }TERPACK;  extern QUEUE gstSpQueue;               extern QUEUE gstTpQueue;  extern TERPACK gstTp;  void ClearQueue(QUEUE *Queue); int IsQueueEmpty(QUEUE *Queue); int IsQueueFull(QUEUE *Queue); int InsertQueue(QUEUE *Queue,unsigned char *lpIn,int nLen); void SetQueueHead(QUEUE *Queue,int nHead); int GetQueueHead(QUEUE *Queue); int TryQueueData(QUEUE *Queue,int nHead,unsigned char *lpOut); int ParseSpData(unsigned char *out_buf, unsigned int *out_len); int ParseTpData(unsigned char *out_buf, unsigned int *out_len); #endif