 #include "base_core.h"
#include "_debug_core_.h"



#if defined(_DBG_2G4_KP_)

void _debug_core__sequence_idsn_init(void);
//
unsigned char get_idsn_and_len(unsigned char kp_type,unsigned char *offset,unsigned char *len);
unsigned char _debug_core__find_idsn_in_list( const unsigned char *rx_sn);	
unsigned char _debug_core__creat_keypad_list(const unsigned char *rx_kp);


//------------------------------0  init parameter ----------------------------------------------------------

//called by debug modual  startup
void _debug_core__init(void)
{
    unsigned char i,j;

    _dbg_core_.idsn_len =0;
    _dbg_core_.valid_kp_cnt =0;
    _dbg_core_.rx_idsn_err_cnt =0;
    _dbg_core_.ack_idsn_err_cnt =0;
    _dbg_core_.txpc_idsn_err_cnt =0;

    for(i=0;i<_DBG_KP_CNT;i++){
        _dbg_core_.kp_info[i].ack_kp_cnt =0;
        _dbg_core_.kp_info[i].rx_kp_cnt =0;
        _dbg_core_.kp_info[i].tx_pc_cnt=0;
        _dbg_core_.kp_info[i].acked_pc_cnt =0;

				#if _DBG_TITLE_CNT !=0
				for(j=0;j<_DBG_TITLE_CNT;j++){
					_dbg_core_.kp_info[i].title_NO[j]=0;
					_dbg_core_.kp_info[i].rpt_title_NO[j]=0;
				}//for
				_dbg_core_.kp_info[i].title_cnt=0;
						
				for(j=0;j<_DBG_ERR_TITLE_CNT;j++){
					_dbg_core_.kp_info[i].err_title_NO[j] =0;
				}
				_dbg_core_.kp_info[i].err_title_cnt =0;
				#endif			
    }//for

     for(i=0;i<11;i++){
         _dbg_core_.rpt_pkt[i].kp_cnt =0;
     }

    #ifdef _DBG_KP_IDSN_CONTINUE
    _debug_core__sequence_idsn_init();
    #endif
}

//extern unsigned short sdk_ack_err_cnt;
//called  when datapos changed!
void _debug_core__init_parameter_datapos_change(void)
{
    unsigned char i,j;
//sdk_ack_err_cnt=0;
    _dbg_core_.rx_idsn_err_cnt =0;
    _dbg_core_.ack_idsn_err_cnt =0;
    _dbg_core_.txpc_idsn_err_cnt =0;    

    for(i=0;i<_DBG_KP_CNT;i++){
        _dbg_core_.kp_info[i].ack_kp_cnt =0;
        _dbg_core_.kp_info[i].rx_kp_cnt =0;
        _dbg_core_.kp_info[i].tx_pc_cnt=0;
        _dbg_core_.kp_info[i].acked_pc_cnt =0;
			
				#if _DBG_TITLE_CNT !=0
				for(j=0;j<_DBG_TITLE_CNT;j++){
					_dbg_core_.kp_info[i].title_NO[j]=0;
					_dbg_core_.kp_info[i].rpt_title_NO[j]=0;
				}//for
				_dbg_core_.kp_info[i].title_cnt=0;
				#endif				
    }//for
}






//---------------------------------- 1 keypad list process ---------------------------------------
#ifndef _DBG_KP_IDSN_CONTINUE
/*
*保存要调试的键盘id/sn名单 
*同时得到idsn_type ；实际有效的键盘个数;
*/
void _debug_core__write_kp_list(unsigned char *list)
{
    unsigned char offset;  

}

/*
* 读出当前调试的键盘名单
*/
void _debug_core__read_kp_list(unsigned char *list)
{


}
#else

//可编号成从1开始的id/sn
void _debug_core__sequence_idsn_init(void)
{
    unsigned char i;
    _dbg_core_.idsn_len =   _DBG_IDSN_LEN;
    _dbg_core_.valid_kp_cnt =_DBG_VALID_KP_CNT;

    for(i=0;i<_DBG_KP_CNT;i++){
        mem_set(_dbg_core_.kp_info[i].kp_idsn,6,0); 
        if(i <= _dbg_core_.valid_kp_cnt){
            _dbg_core_.kp_info[i].kp_idsn[_dbg_core_.idsn_len-1] = i;
        }       
    }//for
}

#endif
/*
*search special SN in keypad list
*return :the offset of special sn in keypad sn list
* -1:not found
*/
static int _mem_cmp_(const unsigned char *ptr1,const unsigned char *ptr2,unsigned char len)
{
    unsigned char i;
    for(i=0;i<len;i++){
        if(ptr1[i] > ptr2[i]) 
            return 1;
        else if(ptr1[i] < ptr2[i]) 
            return -1;           
    }    
    return 0;
}

//search sn in keypad sn list
static int _debug_core__search_kp_list(const unsigned char *sn)
{
    struct _debug_keypad_info_STR *list =_dbg_core_.kp_info;
    unsigned char sum =_dbg_core_.valid_kp_cnt;
    unsigned char idsn_len = _dbg_core_.idsn_len;

    unsigned char low,mid,high;
    int cmp_rslt;
    low =0;
    high = sum; //-1??

    while(low<=high){
        mid=(low+high)/2;   //计算中间元素序号 			
				cmp_rslt =_mem_cmp_(_dbg_core_.kp_info[mid].kp_idsn,sn,idsn_len);
        //cmp_rslt =_mem_cmp_(list[mid].kp_idsn,sn,idsn_len);
        if( cmp_rslt ==0 )
            return mid;
        else if(cmp_rslt >0 )
            high =mid-1;
        else
            low = mid +1;
    }//while

    return -1;
}






//---------------------------------- 2 RX keypad ---------------------------------------

static void get_idsnlen_and_offset(unsigned char data_type,unsigned char *idsn_len,unsigned char *index)
{
    //unsigned char idsn_len=0;
    switch (data_type){
    case 0x91:
        *idsn_len =2;
        *index =2;
        break;
    
    case 0x92:
        *idsn_len =6;
        *index =3;
        break;

    case 0x93:
    case 0x94:    
        *idsn_len =4;
        *index =3;
        break;

    default:
        break;
    }

    //return idsn_len;
}
/*
* 检测键盘的数据处理函数
* Input:
* rx_kp[0] -- len
* rx_kp[1] -- 0x91/92/93,94
*/
void _debug_core__record_rxkp_info(const unsigned char *rx_kp)
{
    unsigned char cur_idsnlen,index;
    int pos;
    if(_dbg_core_.valid_kp_cnt ==0) return;

    get_idsnlen_and_offset(rx_kp[1],&cur_idsnlen,&index);
    if(_dbg_core_.idsn_len !=  cur_idsnlen) return;

    pos =_debug_core__search_kp_list( rx_kp+index);
    if(pos ==-1){//idsn not found in list
        if(_dbg_core_.rx_idsn_err_cnt < _DBG_ERR_CNT){//to prevent overflow 
            //record error SN          
            mem_cpy(rx_kp+index,_dbg_core_.rx_idsn_err[_dbg_core_.rx_idsn_err_cnt],_dbg_core_.idsn_len);			
            _dbg_core_.rx_idsn_err_cnt++;
        }       
    }
    else{
				#if 0
        _dbg_core_.kp_info[pos].rx_kp_cnt++;
				#else
				#if _DBG_TITLE_CNT !=0
				{//题号检测
					unsigned char title= rx_kp[index+8];
					if( (title==0) ||(title >200) || (rx_kp[index-1] !=7) ){
						//error
						if( _dbg_core_.kp_info[pos].err_title_cnt<_DBG_ERR_TITLE_CNT){
							unsigned char err_seq = _dbg_core_.kp_info[pos].err_title_cnt;
							_dbg_core_.kp_info[pos].err_title_NO[err_seq] = title;
							_dbg_core_.kp_info[pos].err_title_cnt++;
						}
					}
					else{
						_dbg_core_.kp_info[pos].rx_kp_cnt++;
						_dbg_core_.kp_info[pos].title_NO[title]++;
					}
				}
				#endif
				
				#endif
    }
}



//---------------------------------- 3 ACK keypad ---------------------------------------
/*
* 根据ack mode =0x15,16,18/19 得出idsn类型
*/
static unsigned char get_idsnlen(unsigned char mode_)
{
    unsigned char idsn_len=0;
    switch (mode_){
    case 0x15:
        idsn_len =2;
        break;
    case 0x16:
        idsn_len =6;
        break;
    case 0x18:
    case 0x19:    
        idsn_len =4;
        break;

    default:
        break;
    }
    return idsn_len;
}
/*
* 检测基站ack键盘的SN是否正确;
* Input:
* ack_kp -- id/sn start address
* mode_type --0x15,16,18/19
* called by 基站ack键盘加载SN数据时调用
*/
void _debug_core__record_ackkp_info(unsigned char mode_type, const unsigned char *ack_kp)
{
    int pos;
    if(_dbg_core_.valid_kp_cnt ==0) return;	
    if( get_idsnlen(mode_type) != _dbg_core_.idsn_len) return;
		
    //全0是空闲时候的ack，不算错误
    if( mem_cmp_const(ack_kp,_dbg_core_.idsn_len,0) ) return;

		pos =_debug_core__search_kp_list(ack_kp);

    if( pos == -1){
        if(_dbg_core_.ack_idsn_err_cnt < _DBG_ERR_CNT){//to prevent overflow
            mem_cpy(ack_kp,_dbg_core_.ack_idsn_err[_dbg_core_.ack_idsn_err_cnt],_dbg_core_.idsn_len);
            _dbg_core_.ack_idsn_err_cnt++;            
        }
        else{
            //error record overflow
        }
    }
    else{
        _dbg_core_.kp_info[pos].ack_kp_cnt++;
    }
}





////----------------------------------4 with PC/SDK ---------------------------------------
/*
* 基站发给pc投票数据，记录其中的键盘信息；
* called by 基站组织/打包数据发送时调用!!!
*/
void _debug_core__record_txpc_info(unsigned char pkt_seq, const unsigned char *tx_pc)
{       
    unsigned char cur_kp= _dbg_core_.rpt_pkt[pkt_seq].kp_cnt;
		int pos;
	
    if( pkt_seq>10) return;  	//to avoid overflow
		if( cur_kp >= KP_MAX_IN_PKT)  return;	//一包最多包含8个键盘数据！！
	
    pos =_debug_core__search_kp_list(tx_pc+2);	//2-offset

    if(pos ==-1){
        if( _dbg_core_.txpc_idsn_err_cnt >=_DBG_ERR_CNT) return ; //to avoid overflow
        //record txpc error sn
        mem_cpy(tx_pc, _dbg_core_.txpc_idsn_err[_dbg_core_.txpc_idsn_err_cnt],_dbg_core_.idsn_len);
        _dbg_core_.txpc_idsn_err_cnt++;
    }
    else{
        _dbg_core_.rpt_pkt[pkt_seq].kp_data[cur_kp] = pos;
        _dbg_core_.rpt_pkt[pkt_seq].kp_cnt++;
        _dbg_core_.kp_info[pos].tx_pc_cnt++; 

				#if _DBG_TITLE_CNT !=0
//				{//题号检测, 上报到sdk的记录
//				unsigned char title= tx_pc[2+8];
//				_dbg_core_.kp_info[pos].title_NO[title] = pkt_seq;
//				}
				#endif
    }
}



/*
* 加载usb 发送之前监测
*/
void _debug_core__record_txpc_info_report(const unsigned char *tx_pc)
{
		unsigned char pkt_seq=tx_pc[4];
    //unsigned char cur_kp= _dbg_core_.rpt_pkt[pkt_seq].kp_cnt;
		int pos;
	
    if( pkt_seq>10) return;  	//to avoid overflow
		//if( cur_kp >= KP_MAX_IN_PKT)  return;	//一包最多包含8个键盘数据！！
//first	
    pos =_debug_core__search_kp_list(tx_pc+2+5);	//2-offset
    if(pos ==-1){
    }
    else{
				#if _DBG_TITLE_CNT !=0
				{//题号检测, 上报到sdk的记录
				unsigned char title= tx_pc[2+8+5];
				_dbg_core_.kp_info[pos].rpt_title_NO[title] = pkt_seq;
				}
				#endif
    }

//second
		if( (tx_pc[2+5+26-1]==0xff)&&(tx_pc[2+5+26]==0xff) ) return;
    pos =_debug_core__search_kp_list(tx_pc+2+5+26);	//2-offset
    if(pos ==-1){
    }
    else{
				#if _DBG_TITLE_CNT !=0
				{//题号检测, 上报到sdk的记录
				unsigned char title= tx_pc[2+8+5+26];
				_dbg_core_.kp_info[pos].rpt_title_NO[title] = pkt_seq;
				}
				#endif
    }		
}





/*
* 记录投票数据中，哪些键盘数据被pc确认接收
* called by 每个packet调用一次
*/
void _debug_core__record_pcack_info(unsigned char pkt_seq)
{
    unsigned char i;
    char pos;

    if( pkt_seq>10) return;		

    for(i=0;i<_dbg_core_.rpt_pkt[pkt_seq].kp_cnt;i++){
        pos =_dbg_core_.rpt_pkt[pkt_seq].kp_data[i];
        _dbg_core_.kp_info[pos].acked_pc_cnt++;				
    }//for
		
    //clear 
    _dbg_core_.rpt_pkt[pkt_seq].kp_cnt =0;
}

#endif 




