#include "svc_factory.h"
#include "../../log/svc/svc_log.h"
#include "../../util/util_data.h"
#include "../../cloud/svc/svc_cloud_protocol.h"
#include "../../bat/svc/svc_bat.h"
#include "../../ir/svc/svc_ir_protocol.h"
#include "../../led/app/app_led.h"
#include "../../lp/svc/svc_lp.h"
#include "../../nb/app/app_nb.h"
#include "../../timer/svc/svc_timer.h"
#include "../../key/svc/svc_key.h"
#include "../../pulse/svc/svc_pulse.h"
#include "../../pulse/svc/svc_pulse_usart.h"
#include "../../ir/svc/svc_ir_uart.h"
#include "hci/led/app/sr_app_led.h"

S_Factory_Data s_fact_data;

static gw_u8 Svc_Factory_Bat_Test(void);
static gw_u8 Svc_Factory_Flash_Test(void);
static void Svc_Factory_Out_Lp(void);

/**
 * @brief: 获取产测变量
 * @return {void}
 * @note: 
 * @see: 
 * @param  
 */
S_Factory_Data* Svc_Factory_Get_Data(void){
	return &s_fact_data;
}

/**
 * @brief: 获取产测变量
 * @return {void}
 * @note: 
 * @see: 
 * @param  
 */
void Svc_Factory_Init(void){
    s_fact_data.u8Func = E_IR_Fun_Start;
}

gw_u8 Svc_Factory_Is_Start(gw_u8* pu8Data,gw_u16 u16Len)
{
		//长度校验
	if(u16Len != 8){
		Svc_FactoryLog_Printf(LOG_ERROR,"%s->len err! len:%d \r\n", __FUNCTION__, u16Len);
		return 0;
	}
	//固定位校验
	if(pu8Data[0] != Frame_header || pu8Data[1] != Type_code || pu8Data[2] != UUT_Device_addr || pu8Data[7] != Frame_end){
		Svc_FactoryLog_Printf(LOG_ERROR,"%s->Frame_header:%d, Type_code:%d UUT_Device_addr:%d Frame_end: \r\n", __FUNCTION__, pu8Data[0], pu8Data[1], pu8Data[2], pu8Data[7]);
		return 0;
	}
	//累加和校验
	if(Util_Data_Check_Sum(pu8Data, 6) != pu8Data[6]){
		Svc_FactoryLog_Printf(LOG_ERROR,"%s->Sum err! \r\n", __FUNCTION__);
		return 0;
	}
	s_fact_data.u8Func = pu8Data[3];
	if(s_fact_data.u8Func == E_IR_Fun_Factory)
	{
		s_fact_data.u8FactoryTest = 1;
		Svc_Factory_Log_Send_Data(s_fact_data.u8Func, 1);
	}
	return 1;
}
/**
 * @brief: 数据解析
 * @return {void}
 * @note: 
 * @see: 
 * @param  {gw_u8*} pu8Data 
 * @param  {gw_u16} u16Len
 */
void Svc_Factory_Log_Parse(gw_u8* pu8Data,gw_u16 u16Len){
	//长度校验
	if(u16Len != 8){
		Svc_FactoryLog_Printf(LOG_ERROR,"%s->len err! len:%d \r\n", __FUNCTION__, u16Len);
		return;
	}
	//固定位校验
	if(pu8Data[0] != Frame_header || pu8Data[1] != Type_code || pu8Data[2] != UUT_Device_addr || pu8Data[7] != Frame_end){
		Svc_FactoryLog_Printf(LOG_ERROR,"%s->Frame_header:%d, Type_code:%d UUT_Device_addr:%d Frame_end: \r\n", __FUNCTION__, pu8Data[0], pu8Data[1], pu8Data[2], pu8Data[7]);
		return;
	}
	//累加和校验
	if(Util_Data_Check_Sum(pu8Data, 6) != pu8Data[6]){
		Svc_FactoryLog_Printf(LOG_ERROR,"%s->Sum err! \r\n", __FUNCTION__);
		return;
	}
	s_fact_data.u8Func = pu8Data[3];
	if(s_fact_data.u8Func == E_IR_Fun_Factory)
	{
		s_fact_data.u8FactoryTest = 1;
		Svc_Factory_Log_Send_Data(s_fact_data.u8Func, 1);
	}	
	//Svc_FactoryLog_Printf(LOG_INFO,"%s->FunCode:0x%02X \r\n", __FUNCTION__, s_fact_data.u8Func);
}

static void Svc_EraseFlash_All(void)
{
	if(Svc_Com_Sys_Get_Work_Mode() == E_FactoryTestMode)
	{
		Svc_Com_Delay_Ms(64,500);
		gw_u16 u16Secoff = FLASH_DEVICE_SECURITY_ADDR/FLASH_SECTOR_SIZE;
		Bsp_Flash_Erase_Sector(u16Secoff);//<<<<<<<<<<<<<<<扇区擦除失败处理，若扇区擦除失败，则写入不成功，所以第一个写入的日期就不对
		gw_u16 u16Secoff1 = FLASH_DEVICE_SECURITY_BAK_ADDR/FLASH_SECTOR_SIZE;
		Bsp_Flash_Erase_Sector(u16Secoff1);//<<<<<<<<<<<<<<<扇区擦除失败处理，若扇区擦除失败，则写入不成功，所以第一个写入的日期就不对
		for(gw_u8 i = 0; i < 100; i++)
		{
			gw_u16 u16Secoff = FLASH_USAGE_DAY_START_ADDR/FLASH_SECTOR_SIZE +i;
			Bsp_Flash_Erase_Sector(u16Secoff);//<<<<<<<<<<<<<<<扇区擦除失败处理，若扇区擦除失败，则写入不成功，所以第一个写入的日期就不对
			Svc_Com_Delay_Ms(2,64);	
		}
		gw_u16 u16Secoff2 = FLASH_USAGE_ADDR/FLASH_SECTOR_SIZE;
		Bsp_Flash_Erase_Sector(u16Secoff2);//<<<<<<<<<<<<<<<扇区擦除失败处理，若扇区擦除失败，则写入不成功，所以第一个写入的日期就不对
		gw_u16 uSecoff3 = FLASH_USAGE_BAK_ADDR/FLASH_SECTOR_SIZE;
		Bsp_Flash_Erase_Sector(uSecoff3);//<<<<<<<<<<<<<<<扇区擦除失败处理，若扇区擦除失败，则写入不成功，所以第一个写入的日期就不对  
		gw_u16 Secoff4 = FLASH_USAGE_DAY_START_ADDR/FLASH_SECTOR_SIZE+2;
		Bsp_Flash_Erase_Sector(Secoff4);//<<<<<<<<<<<<<<<扇区擦除失败处理，若扇区擦除失败，则写入不成功，所以第一个写入的日期就不对
		gw_u16 Secoff7 = FLASH_USAGE_DAY_START_ADDR/FLASH_SECTOR_SIZE+3;
		Bsp_Flash_Erase_Sector(Secoff7);//<<<<<<<<<<<<<<<扇区擦除失败处理，若扇区擦除失败，则写入不成功，所以第一个写入的日期就不对
		gw_u16 Secoff8 = FLASH_USAGE_DAY_START_ADDR/FLASH_SECTOR_SIZE+4;
		Bsp_Flash_Erase_Sector(Secoff8);//<<<<<<<<<<<<<<<扇区擦除失败处理，若扇区擦除失败，则写入不成功，所以第一个写入的日期就不对
		gw_u16 Secoff5 = FLASH_DEVICE_PARA_ADDR /FLASH_SECTOR_SIZE;
		Bsp_Flash_Erase_Sector(Secoff5);//<<<<<<<<<<<<<<<扇区擦除失败处理，若 扇区擦除失败，则写入不成功，所以第一个写入的日期就不对
		gw_u16 Secoff6 = FLASH_DEVICE_PARA_BAK_ADDR /FLASH_SECTOR_SIZE;
		Bsp_Flash_Erase_Sector(Secoff6);//<<<<<<<<<<<<<<<扇区擦除失败处理，若扇区擦除失败，则写入不成功，所以第一个写入的日期就不对        
	}
}

/**
 * @brief: 产测命令处理
 * @return {void}
 * @note: '
 * @see: 
 * @param  
 */
void Svc_Factory_Command_Deal(void)
{
	switch(s_fact_data.u8Func)
	{
		case E_IR_Fun_Start:
			Svc_Factory_Log_Send_Data(s_fact_data.u8Func, 1);
			s_fact_data.u8Func = E_IR_Fun_Null;
			break;
		case E_IR_Fun_Ir:
			Svc_Factory_Ir_Send_Data(s_fact_data.u8Func, 1);
			break;			
		case E_IR_Fun_IMEI:
			if(s_fact_data.u8Flag_IMEI){
				Svc_Factory_Log_Send_Data(s_fact_data.u8Func, 1);
			}
			break;
		case E_IR_Fun_IMSI:
			if(s_fact_data.u8Flag_IMSI){
				Svc_Factory_Log_Send_Data(s_fact_data.u8Func, 1);
			}
			break;
		case E_IR_Fun_ICCID:
			if(s_fact_data.u8Flag_ICCID){
				Svc_Factory_Log_Send_Data(s_fact_data.u8Func, 1);
			}
			break;
		case E_IR_Fun_RSRP:
			if(s_fact_data.u8Flag_RSRP){
				Svc_Factory_Log_Send_Data(s_fact_data.u8Func, 1);
			}
			break;
		case E_IR_Fun_Flash:
			Svc_Factory_Log_Send_Data(s_fact_data.u8Func, Svc_Factory_Flash_Test());
			break;
		case E_IR_Fun_Bat:
			Svc_Factory_Log_Send_Data(s_fact_data.u8Func, Svc_Factory_Bat_Test());
			break;
		case E_IR_Fun_Lp:
			Svc_Factory_Log_Send_Data(s_fact_data.u8Func, 1);
			Svc_Timer_Delay_Ms(1000);
			s_fact_data.u8Flag_Lp = 1;
			break;
		case E_IR_Fun_WHOLE:
			Svc_Pulse_GetN(); 
			s_fact_data.u8Func = E_IR_Fun_Null;
			break;			
		case E_IR_Fun_WDG:
            Bsp_Com_Rst_Reason();
			if(s_fact_data.u8Flag_NRST){			//有复位标志，发送数据
				s_fact_data.u8Flag_NRST = 0;
				Svc_Factory_Log_Send_Data(E_IR_Fun_WDG, 1);
			}			
			break;            
		default:break;
	}
	if(s_fact_data.u8Flag_Mag == 1){//有磁唤醒标志，发送数据
		s_fact_data.u8Flag_Mag = 0;
		s_fact_data.u8Flag_Lp = 0;		//清除低功耗标志
		Svc_Log_Wake_Init();			//唤醒后，发送数据前需初始化
        Svc_Timer_Delay_Ms(1000);
		Svc_Factory_Log_Send_Data(E_IR_Fun_Mag, 1);
	}	
	if(s_fact_data.u8Flag_Lp){			//有低功耗标志，进入低功耗
		Svc_Factory_Into_Lp();
		Svc_Factory_Out_Lp();
	}	
}

/**
 * @brief: 发送数据
 * @return {void}
 * @note: 
 * @see: 
 * @param  {gw_u8}u8Func:功能码
 * @param  {gw_u8}u8Succ:结果 0-失败 1-成功
 */
void Svc_Factory_Log_Send_Data(gw_u8 u8Func, gw_u8 u8Succ)
{
	gw_u8 u8Data[30] = {0};
	S_Pulse_Uart* s_pulse_uart;
	s_pulse_uart = Svc_Pulse_Get_Data();	
	gw_u8 u8DataLen = 1;		//数据长度，默认为1
	
	u8Data[0] = Frame_header;
	u8Data[1] = Type_code;
	u8Data[2] = PC_Device_addr;
	u8Data[3] = u8Func;
	u8Data[5] = u8Succ;	//数据内容
	
	switch(u8Func)
	{
		case E_IR_Fun_WHOLE:
			u8DataLen = 19;
			memcpy(&u8Data[5], s_pulse_uart->RX_PULSE_DATA,19);
			break;
		case E_IR_Fun_IMEI:
			u8DataLen = 15;
			Svc_Cloud_Get_Imei(&u8Data[5]);
			break;
		case E_IR_Fun_IMSI:
			u8DataLen = 15;
			Svc_Cloud_Get_Imsi(&u8Data[5]);
			break;
		case E_IR_Fun_ICCID:
			u8DataLen = 20;
			Svc_Cloud_Get_Iccid(&u8Data[5]);
			break;
		case E_IR_Fun_RSRP:
			{
				S_Cloud_Data *ps_cloud_data = Svc_Cloud_Get_Data();
				memcpy(&u8Data[5], &ps_cloud_data->s16Rsrp,2);
				u8DataLen = 3;
			}
			break;
		case E_IR_Fun_Bat:
			{
				gw_u32 u32Bat = Bsp_Bat_Get_Adc();
				gw_u8 u8bat[2];
				u8bat[0] = u32Bat&0x000000FF;//引导码
    			u8bat[1]= (u32Bat&0x0000FF00)>>8;
				memcpy(&u8Data[5], u8bat,2);
				u8DataLen = 2;
			}
			break;
		default:break;
	}
	u8Data[4] = u8DataLen;	//数据长度
	u8Data[5 + u8DataLen] = Util_Data_Check_Sum(u8Data, 5 + u8DataLen);//累加和
	u8Data[6 + u8DataLen] = Frame_end;
	if(Svc_Com_Sys_Get_Work_Mode()==E_FactoryTestMode){
		Bsp_Log_Send_Bytes((gw_s8*)u8Data, u8DataLen + 7);
	}
	if(u8Func == E_IR_Fun_Factory || u8Func == E_IR_Fun_WHOLE)
	{
		Bsp_Ir_Uart_Send_Bytes((gw_s8*)u8Data, u8DataLen + 7);
		Svc_Timer_Delay_Ms(100);
	}
	s_fact_data.u8Func = E_IR_Fun_Null;//清除功能码
}


/**
 * @brief: 电池电压测试
 * @return {gw_u8}0-失败 1-成功
 * @note: 
 * @see: 
 * @param  
 */
static gw_u8 Svc_Factory_Bat_Test(void)
{
	gw_u32 u32Bat = Bsp_Bat_Get_Adc();
	
	Svc_FactoryLog_Printf(LOG_INFO,"%s->Battery voltage:%d mv", __FUNCTION__, (gw_u16)u32Bat);
	if(u32Bat > 3500 || u32Bat < 3700){return 1;}
	else{return 0;}
}

typedef struct{
    gw_u8   u8Sig;   
    gw_u8   pu8Data[5];			
    gw_u8   u8CheckSum;  
}S_FACTORY_FLASH;

const gw_u8 pu8Data[5] = {0x11, 0x22, 0x33, 0x44, 0x55};//存入flash的内容
#define FLASH_FACTORY_ADDR		0x00024000								//产测存放数据地址，已看过和平常存储不在同一个位置

/**
 * @brief: 读取产测flash测试数据
 * @return {E_Result_State}
 * @note: 
 * @see: 
 * @param  
 */
static E_Result_State Check_Factory_Flash(void){
	
	S_FACTORY_FLASH s_factory_flash;
	
	Svc_Flash_Read(&s_factory_flash.u8Sig, FLASH_FACTORY_ADDR,sizeof(s_factory_flash));
	//标志检查
	if(s_factory_flash.u8Sig!=FLASH_SIG_USED){
			Svc_FactoryLog_Printf(LOG_WARNING,"%s->check sig fail",__FUNCTION__);
			return E_STATE_ERROR;
	}
	//和校验检查
	if(s_factory_flash.u8CheckSum != Util_Data_Check_Sum(&s_factory_flash.u8Sig, 6)){
			Svc_FactoryLog_Printf(LOG_WARNING,"%s->check sum fail",__FUNCTION__);
			return E_STATE_ERROR;
	}
	//内容检查
	if(memcmp(&s_factory_flash.pu8Data, pu8Data, 5)){
			Svc_FactoryLog_Printf(LOG_WARNING,"%s->check data fail",__FUNCTION__);
			return E_STATE_ERROR;
	}
	return E_STATE_SUCCESS;
}

/**
 * @brief: flash测试
 * @return {gw_u8}0-失败 1-成功
 * @note: 
 * @see: 
 * @param  
 */
static gw_u8 Svc_Factory_Flash_Test(void)
{
	S_FACTORY_FLASH s_factory_flash;
		//参数填充
    s_factory_flash.u8Sig = FLASH_SIG_USED;
	memcpy(s_factory_flash.pu8Data, pu8Data, 5);
    s_factory_flash.u8CheckSum = Util_Data_Check_Sum(&s_factory_flash.u8Sig, 6);
    //写数据
    Svc_Flash_Write(&s_factory_flash.u8Sig, FLASH_FACTORY_ADDR, sizeof(s_factory_flash));
    //读写入数据进行校验
    if(Check_Factory_Flash() == E_STATE_ERROR){
        Svc_FactoryLog_Printf(LOG_ERROR,"%s->write fail",__FUNCTION__);
        return 0;
    }
	// Svc_EraseFlash_All();	
    return 1;
}

/**
 * @brief: 进入低功耗
 * @return 
 * @note: 
 * @see: 
 * @param  
 */
void Svc_Factory_Into_Lp(void)
{
	if(Svc_Com_Sys_Get_Work_Mode()==E_FactoryTestMode){
		SR_AppLedClearWork(LED_NB_NET_INIT);
		SR_AppLedClearWork(LED_IR_OPEN);
		s_fact_data.u8Flag_Mag = 2;		
		Bsp_Lp_Func_Disable();
    	Bsp_Lp_Gpio_Setting();
    	Bsp_Lp_Sleep();
    }
	if(s_fact_data.u8FactoryLowp == 1)
	{
		Bsp_Lp_Func_Disable();
    	Bsp_Lp_Gpio_Setting();
    	Bsp_Lp_Sleep();
	}
}

static void Svc_Factory_Out_Lp(void)
{
	Svc_Log_Init();
    Func_Init();
}


/**
 * @brief: 磁开关，中断初始化
 * @return 
 * @note: 
 * @see: 
 * @param  
 */
void Svc_Factory_Mag_Init(void)
{
	Bsp_Com_Dis_Interrupts();    //关中断    		
    Bsp_Key_Gpio_Init();
    Bsp_Com_En_Interrupts(); 
}

// /**
//  * @brief: 看门狗复位检查
//  * @return 
//  * @note: 
//  * @see: 
//  * @param
//  */
// void Svc_Factory_Rst_Check(void)
// {
//     if(Check_Factory_Flash() == E_STATE_SUCCESS){
// 		gw_u32 secpos = 0;
// 		s_fact_data.u8Flag_WDG = 1;
// 		Svc_FactoryLog_Printf(LOG_INFO,"%s->WDT Rst!",__FUNCTION__);
// 		Svc_Flash_Power_On();
// 		Svc_Com_Delay_Ms(64,5);
// 		secpos = FLASH_FACTORY_ADDR/FLASH_SECTOR_SIZE;//扇区地址 0~511 for w25x16
//         Bsp_Flash_Erase_Sector(secpos);//扇区擦除
// 		Svc_Flash_Power_Off();
//     }
// }














