#include "base_core_user.h"
#include "function.h"
#include "string.h"
#include "platform_interface.h"
#include "stdint.h"
#include "base_pc_protocol.h"

//#define RTT_DEBUG


#ifdef RTT_DEBUG
#include "SEGGER_RTT.h"
#include "SEGGER_RTT_Conf.h"
#endif

#if (TEXT_MESSAGE)

#define WAIT_TXOK_TIMER 500
#define BEACON_RECOVER_COUNTDOWN 11
#define MSG_BUF_LEN     1056

void set_tx_ok_flag(unsigned char flag);
unsigned char get_tx_ok_flag(void);
void basic_delay_us( unsigned short time );

struct text_msg_STR
{
    unsigned char status;
    unsigned char data_ok_flag;
    unsigned char buf[MSG_BUF_LEN+1];
//	unsigned char *buf;
    unsigned char rf_pack_index;
    unsigned int buf_len;
	unsigned int pc_pack_all;
	unsigned int pc_pack_cnt;
	unsigned int pc_pack_index;
    unsigned int send_len;
    unsigned int timer_cnt; 
    unsigned char recover_cutdown;
	unsigned char data_change;
};

unsigned char RF_Send_buf[MSG_BUF_LEN+1]={0};


struct text_msg_STR msg={0};
uint16_t msg_outtime_cnt=0;


typedef union {
    unsigned int dec;
    unsigned char part[4];
} byte2str;

byte2str Byte2Dex;

uint16_t msg_delay_us(uint32_t time)
{
    basic_delay_us(time);
}

void Msg_TickHandler(void)
{
    if (msg_outtime_cnt)
    {
        if (--msg_outtime_cnt == 0)
        {
			msg.data_ok_flag=0;
            msg.buf_len=0;
			msg.pc_pack_all=0;
			msg.pc_pack_cnt=0;
        }
    }
}

//unsigned char msg_get_pc_data(uint8_t flag, const unsigned char *buf, unsigned char pack_all,unsigned int buf_len)
//{
//	if(msg.buf_len==0)
//    {
//        memset(msg.buf, 0, MSG_BUF_LEN);
//		msg.pc_pack_all=pack_all;
//    }

//    if(msg.buf_len+buf_len>MSG_BUF_LEN)
//    {
//        msg.data_ok_flag=0;
//        memset(msg.buf, 0, MSG_BUF_LEN);
//        msg.buf_len=0;
//		msg.pc_pack_all=0;
//		msg.pc_pack_cnt=0;
//        return 1;
//    }
//	msg.pc_pack_cnt++;
//	if(msg.pc_pack_cnt>msg.pc_pack_all)
//	{
////		msg.data_ok_flag=0;
////		memset(msg.buf, 0, MSG_BUF_LEN);
////		msg.buf_len=0;
////		msg.pc_pack_all=0;
////		msg.pc_pack_cnt=0;
////        return 1;
//	}
//	
//    
//    memcpy(msg.buf + msg.buf_len,buf,buf_len);
//    msg.buf_len+=buf_len;
//	
//	
//    msg_outtime_cnt=5;
//    if(flag)     
//    {   msg.send_len=msg.buf_len;
//        msg.data_ok_flag=1;
//        msg.pack_index++;
//        
//		msg_outtime_cnt=0;
//        msg.buf_len=0; 
//		msg.pc_pack_all=0;
//		msg.pc_pack_cnt=0;
//    }
//    
//    return 0;

////    else    
////        return 1;
//}


//unsigned char msg_get_pc_data(const unsigned char *buf)
unsigned char msg_get_pc_data(const unsigned char *PC_buf)//, unsigned char *Save_buf)
{
    uint16_t i;
	
//	msg.buf=Save_buf;
	if(msg.buf_len==0)
    {
        memset(msg.buf, 0, MSG_BUF_LEN);
		msg.pc_pack_all=*(PC_buf+6);
		msg.pc_pack_index=((PC_buf[7]*16) + PC_buf[8]);
		if((PC_buf[7]*16) + PC_buf[8]) 
			return 1;
    }
	else
	{
		if(msg.pc_pack_index==((PC_buf[7]*16) + PC_buf[8])) 
			return 2;
		msg.pc_pack_index=(PC_buf[7]*16) + PC_buf[8];
	}
	
    if((msg.buf_len+48)>MSG_BUF_LEN)
    {
        msg.data_ok_flag=0;
        memset(msg.buf, 0, MSG_BUF_LEN);
        msg.buf_len=0;
		msg.pc_pack_all=0;
		msg.pc_pack_cnt=0;
        return 3;
    }
	
	msg.pc_pack_cnt++;
	if(msg.pc_pack_cnt>msg.pc_pack_all)
	{
		msg.data_ok_flag=0;
		memset(msg.buf, 0, MSG_BUF_LEN);
		msg.buf_len=0;
		msg.pc_pack_all=0;
		msg.pc_pack_cnt=0;
        return 4;
	}
    
    memcpy(msg.buf + msg.buf_len,PC_buf+9,48);
    msg.buf_len+=48;
    msg_outtime_cnt=5;
    if((msg.pc_pack_index+1)>=msg.pc_pack_all )     
    {   msg.send_len=msg.buf_len;
        
        msg.data_ok_flag=1;
        msg.rf_pack_index++;
        msg.timer_cnt=0;
        msg.data_change=1;
		msg_outtime_cnt=0;
//        msg.buf_len=0; 
//		msg.pc_pack_all=0;
//		msg.pc_pack_cnt=0;
    }
    
    return 0;
}

uint8_t msg_tx_payload(uint8_t *Payload, uint32_t Length)
{
    //return Platform.RF_TxPack(Payload, Length);
    set_tx_ok_flag(0);
    platform.rf_send_data(Payload, Length, base_core.get_mainRF_hard_id());
    return 1;
}



void msg_wait_rfsendOK()
{
    uint8_t status;
    uint16_t wait = WAIT_TXOK_TIMER;

    while (wait)
    {
        if (get_tx_ok_flag())
            return;
        msg_delay_us(2);
        wait--;
    }
}

#ifdef RTT_DEBUG
void msg_rtt_log(uint8_t index, uint8_t *buf)
{
    uint16_t send_len=0;
    char temp[50]={0};
    uint16_t i;
    uint16_t msg_len;
	uint16_t rtn=0;
	uint8_t cnt=0;
    
    while (send_len<msg.send_len && rtn==0)
    {
        Byte2Dex.part[0]=buf[send_len+3];
        Byte2Dex.part[1]=buf[send_len+2];
        Byte2Dex.part[2]=buf[send_len+1];
        Byte2Dex.part[3]=buf[send_len+0];
        
        if(Byte2Dex.part[0]==0) break;
        msg_len=buf[send_len+6];
        if(msg_len>7 && msg_len<48 )
        {
			for(cnt=7;cnt<msg_len;cnt++)
			{
				if(buf[send_len+cnt]<'0')
				{
					rtn=send_len;
					break;
				}
			}
            send_len+=msg_len;

        }
        else
        {
            send_len+=7;
        }
        
    }
	
	if(rtn)
	{
		
		SEGGER_RTT_printf(0,"\n-------------------------%d------------------------\n",index);
		SEGGER_RTT_printf(0,"position:%d,buf_len:%02d\n",rtn,msg.send_len);
		
		for(i=0;i<1024;i+=46)
		{
			SEGGER_RTT_printf(0,"%04d: %02x %02x %02x %02x   %02x %02x %02x   %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n"
			,i,
			buf[i+0],buf[i+1],buf[i+2],buf[i+3],buf[i+4],buf[i+5],buf[i+6],buf[i+7],buf[i+8],buf[i+9],buf[i+10],buf[i+11],buf[i+12],buf[i+3],buf[i+14],buf[i+15],
			buf[i+16],buf[i+17],buf[i+18],buf[i+19],buf[i+20],buf[i+21],buf[i+22],buf[i+23],buf[i+24],buf[i+25],buf[i+26],buf[i+27],buf[i+28],buf[i+29],buf[i+30],buf[i+31],
			buf[i+32],buf[i+33],buf[i+34],buf[i+35],buf[i+36],buf[i+37],buf[i+38],buf[i+39],buf[i+40],buf[i+41],buf[i+42],buf[i+43],buf[i+44],buf[i+45]
			);
			msg_delay_us(400);
			
		}
		SEGGER_RTT_printf(0,"\n-------------------------%d------------------------\n",index);
		
	}
}
#endif
void msg_send(uint8_t *Send_buf)
{
    uint8_t buf[40] = {0};
    uint16_t Crc = 0;
    uint16_t send_len=0;
    
    base_core.get_match_code(buf);//buf[0]~buf[3],MATCHCODE

    buf[4] = 0xFE;
    buf[5] = 0x48;                  
    buf[6] = 0xDE; 
    buf[7] = 0x9E;                  

    buf[8] = ((msg.send_len+31)/32);
    
    buf[9] = 0x01;//transparent transmission
   
    Crc = crc16(Send_buf, buf[8]*32);
    buf[10] = Crc>>8; 
    buf[11] = Crc&0xFF;
    
    buf[12] = msg.rf_pack_index;
    memset(buf+13,0,19);
    msg_tx_payload(buf, 32);
    msg_wait_rfsendOK();
    msg_delay_us(200);
	#ifdef RTT_DEBUG
    msg_rtt_log(msg.rf_pack_index,Send_buf);
	#endif
    while (send_len<msg.send_len)
    {
        msg_tx_payload(Send_buf + send_len, 32);
        msg_wait_rfsendOK();
        msg_delay_us(50);
        send_len+=32;
    }
}


extern void base_send_beacon_switch(unsigned char sw);
void msg_polling(void)
{
    if(!msg.status) return;
	
	if(msg.data_change)
	{
		msg.data_change=0;
//		if(msg.buf)
		{
			memcpy(RF_Send_buf, msg.buf, msg.buf_len);
			msg.buf_len=0; 
			msg.pc_pack_all=0;
			msg.pc_pack_cnt=0;
		}
		
	}
	
    msg_send(RF_Send_buf);
    base_send_beacon_switch(2);
    msg.status=0;
}

unsigned char msg_issendtime(void)
{
//    uint8_t buf[1500];
//    if( base_core.get_run_status() !=_STA_SYSMODE_0 ) return 0;
//    if(!msg.data_ok_flag ) return 0;
//    if((msg.timer_cnt++)%6==0)
//    {
//        msg_set_status(1);
//        msg.recover_cutdown=BEACON_RECOVER_COUNTDOWN;
//        return 1;
//    }
//    else
//    {
//        if(msg.timer_cnt>300)
//        {
//            msg.data_ok_flag=0;
//            msg.timer_cnt=0;
//        }
//    } 
//    return 0;
    
    
    uint8_t buf[1500];
    if( base_core.get_run_status() !=_STA_SYSMODE_0 ) return 0;
    if(!msg.data_ok_flag ) return 0;
    if(basic_beacon_crs2.pack_cnt==7)
    {
        basic_beacon_crs2.pack_cnt=0;
        msg_set_status(1);
        msg.recover_cutdown=BEACON_RECOVER_COUNTDOWN;
        return 1;
    }
    
    msg.timer_cnt++;
    {
        if(msg.timer_cnt>300)
        {
            msg.data_ok_flag=0;
            msg.timer_cnt=0;
        }
    } 
    return 0;
}

void msg_recover_beacon_countdown(void)
{
    if(msg.recover_cutdown)
    {
        if(msg.recover_cutdown>BEACON_RECOVER_COUNTDOWN) msg.recover_cutdown=BEACON_RECOVER_COUNTDOWN;
        msg.recover_cutdown--;
        if(msg.recover_cutdown==0)
        {
//            base_send_beacon_switch(2);
        }
    }
}

unsigned char msg_get_status(void)
{
    return msg.status;
}

void msg_set_status(unsigned char status)
{
    msg.status=status;
}

void msg_clr_len(void)
{
    msg.buf_len=0; 
}    

#endif
