rspackage_dle.c 4.97 KB
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rspackage_dle.h>

char  *rs_error_string( void)
/**
    @brief  ini_error_code에 대한 에러 설명 문자열을 반환
    @return 에러 코드에 대한 에러 설명 문자열 포인터
    @warning 절대 반환 받은 문자열을 소멸 시켜서는 안 된다!!
*/
{
   char *error_string[] ={ "에러 없음",                                         //  RSERR_NONE         
                           "메모리 부족",                                       //  RSERR_OUT_OF_MEMORY
                           "CRC 에러",                                          //  RSERR_CRC          
                           "자료 구조 이상"                                     //  RSERR_DATA         
                         };
                        
   return( error_string[rspackage_error_code]);
}

char *rs_put_dle( rs_dle_t *dle, char *data, int size)
{                                      
    char    datum;
    int     col;
    int     ndx;
    int     branch;
    
    
    branch  = __WAIT_DLE;   
    col     = 0;    
    for ( ndx = 0; ndx < size; ndx++)
    {
        datum = *data++;
        switch( branch)
        {
        case __WAIT_DLE   :
                        if  ( dle->ch_dle == datum)
                        {
                            branch = __WAIT_STX;
                        }
                        break;
        case __WAIT_STX   :
                        if ( dle->ch_stx == datum)
                        {
                            branch    = __RCV_DATA;
                        }
                        else
                        {
                            dle->sz_data          = -1;                         // CRC 에러 또는 데이터 이상
                            rspackage_error_code  = RSERR_DATA;
                            return data;                                        // 지금까지 처리한 이후의 포인터를 반환
                        }
                        break;
        case __RCV_DATA   :
                        if  ( dle->ch_dle == datum)
                        {
                            branch = __CHK_DLE;
                        }                
                        else
                        {
                            dle->buffer[col++] = datum;
                        }
                        break;
        case __CHK_DLE    :
                        if  ( dle->ch_dle == datum)
                        {
                            dle->buffer[col++] = dle->ch_dle;
                            branch = __RCV_DATA;
                        }
                        else if ( dle->ch_etx == datum)
                        {
                            dle->sz_data    = col;
                            if ( dle->check_crc( dle))
                            {
                                return data;
                            }
                            else
                            {               
                                dle->sz_data          = -1;                     // CRC 에러 또는 데이터 이상
                                rspackage_error_code  = RSERR_CRC;
                            }    
                            return data;    
                        }
                        else                                                    // DLE 다음에 와서는 안되는 코드가 왔으므로 실표로 반한
                        {
                            dle->sz_data          = -1;                         // CRC 에러 또는 데이터 이상
                            rspackage_error_code  = RSERR_DATA;
                            return data;                                        // 지금까지 처리한 이후의 포인터를 반환
                        }
                        break;
        } // switch()
    } // for {}
    dle->sz_data          = 0;                                                  // 수신된 데이터가 없음
    rspackage_error_code  = RSERR_NONE;
    return data;                                                                // 지금까지 처리한 이후의 포인터를 반환
}

rs_dle_t *rs_create_dle( int  (*check_crc)( rs_dle_t *))
{
    rs_dle_t *dle;
    
    dle = ( rs_dle_t *)malloc( sizeof( rs_dle_t));
    if ( NULL == dle)
    {               
        rspackage_error_code    = RSERR_OUT_OF_MEMORY;        
        return NULL;
    }                                   
    dle->ch_stx             = 0x02;
    dle->ch_etx             = 0x03;
    dle->ch_dle             = 0x10;
    dle->check_crc          = check_crc;
    rspackage_error_code    = RSERR_NONE;
    return dle;        
}

int rs_make_packet( rs_dle_t *dle, char *dst_buf, char *src_buf, int src_cnt )
{
	int   loop;
	char  *dst, *src;
	
	dst = dst_buf;
	src = src_buf;
	
	*dst++ = dle->ch_dle;
	*dst++ = dle->ch_stx;
	
	for( loop=0; loop<src_cnt; loop++ )
	{
		if ( *src == dle->ch_dle )
		{
			*dst++ = dle->ch_dle;
		}
		
		*dst++ = *src++;
	}
	
	*dst++ = dle->ch_dle;
	*dst++ = dle->ch_etx;
	
	return dst - dst_buf;
}