#include "protools.h"
struct CAR_DATA_STR CarRecDataStr = {0};
uint8_t CycleDetectionTime = 0;
enum SIGNAL_STATE SingalCheck(void)
{
    u8 reccs;
    int i;
    uint8_t DealRecData[25] = {0};
    uint8_t ID_LOCK[3] = {0x35,0x19,0x13};
    memcpy(ID_LOCK,SystemPara.LockID,3*sizeof(uint8_t));
    if(!SX78Str.Sx7xRxFlag)return ERR;
    if((SX78Str.SX7xRxStr[0]!=ID_LOCK[0])||(SX78Str.SX7xRxStr[1]!=ID_LOCK[1]))return ERR;
    SX78Str.Sx7xRxFlag = FALSE;
    memcpy(DealRecData,SX78Str.SX7xRxStr+3,25*sizeof(uint8_t));
    memset(SX78Str.SX7xRxStr,0,0x80*2*sizeof(uint8_t));
    if(DealRecData[0]==0xFB&&DealRecData[1]==0x00&&DealRecData[2]==0x00&&DealRecData[3]==0x00&&DealRecData[4]==0xFD)
    {
        return BOOT ;
    }
    if(DealRecData[0]==0xFB&&DealRecData[1]==0x11&&DealRecData[2]==0x11&&DealRecData[3]==0x11&&DealRecData[4]==0xFD)
    {
        return TEST_REC ;
    }
    if(DealRecData[0]==0X7B&&DealRecData[1]==0X10&&DealRecData[4]==0X07&&DealRecData[5]==0XFF&&DealRecData[19]==0X7D)
    {
        return ERR;
    }
    //enum SIGNAL_STATE MAG = 1;//photores_dete();//返回地磁变化状态。
    //载荷长度为5的命令解析。
    if(DealRecData[0]==0x7B&&DealRecData[8]==0x7D&&DealRecData[1]==0x05)
    {

        reccs=0;
        for(i=2; i<7; i++)
        {
            reccs=reccs+DealRecData[i];
        }
        if(reccs==DealRecData[7])//校验和正确。
        {
            if((DealRecData[2]==ID_LOCK[0]&&DealRecData[3]==ID_LOCK[1])||(DealRecData[2]==0xFF&&DealRecData[3]==0xFF))//lock地址或广播地址
            {
                //LedCtrl(SINGLE);
                //对02寄存器写操作。

                if(DealRecData[4]==0x06&&DealRecData[5]==0x02&&DealRecData[6]==0x00)//命令06 寄存器02
                {
                    return PC_OPEN;

                }
                if(DealRecData[4]==0x06&&DealRecData[5]==0x02&&DealRecData[6]==0x01)
                {
                    return PC_CLOSE;
                }
                if(DealRecData[4]==0x06&&DealRecData[5]==0x03&&DealRecData[6]==0x00)
                {
                    return ALL_OPEN;
                }
                if(DealRecData[4]==0x06&&DealRecData[5]==0x03&&DealRecData[6]==0x01)
                {
                    return ALL_CLOSE;
                }
                if(DealRecData[4]==0x06&&DealRecData[5]==0x09&&DealRecData[6]==0x00)
                {
                    return SET_BEEP_0;
                }
                if(DealRecData[4]==0x06&&DealRecData[5]==0x0E&&DealRecData[6]==0x00)
                {
                    return SET_CAR_NO_STATE;
                }
                if(DealRecData[4]==0x06&&DealRecData[5]==0x0E&&DealRecData[6]==0x01)
                {
                    return SET_CAR_YES_STATE;
                }

            }
        }
    }

    //载荷长度为4的命令
    if(DealRecData[0]==0x7B&&DealRecData[7]==0x7D&&DealRecData[1]==0x04)
    {
        reccs=0;

        for(i=2; i<6; i++)
        {
            reccs=reccs+DealRecData[i];
        }

        if(reccs==DealRecData[6])
        {
            if((DealRecData[2]==ID_LOCK[0]&&DealRecData[3]==ID_LOCK[1])||(DealRecData[2]==0xFF&&DealRecData[3]==0xFF))
            {

                if(DealRecData[4]==0x03)
                {
                    switch(DealRecData[5])
                    {
                      case 0xFF:
                        return PC_REQ;
                      case 0x08:
                        return GET_OPT_PA;
                      case 0x07:
                        return GET_ADDED_WL_PC;
                      case 0x05:
                        return GET_ADDED_WL_LOCK;
                      case 0x0B:
                        return GET_CURRENT_PARA;
                      case 0x0D:
                        return GET_WL_PARA;
                      case 0x0F:
                        return GET_PHO_PARA;
                      case 0x10:
                        return BatLowValueRead;
                      default:
                        break;
                    }

                }
            }
        }
    }

    //载荷长度为6的数据包。

    if(DealRecData[0]==0x7B&&DealRecData[9]==0x7D&&DealRecData[1]==0x06)
    {
        reccs=0;

        for(i=2; i<8; i++)
        {
            reccs=reccs+DealRecData[i];
        }
        //
        if(reccs==DealRecData[8])
        {
            if((DealRecData[2]==ID_LOCK[0]&&DealRecData[3]==ID_LOCK[1])||(DealRecData[2]==0xFF&&DealRecData[3]==0xFF))
            {
                if(DealRecData[4]==0x06)//写指令
                {
                    if(DealRecData[5]==0x00)
                    {
                        return ADDED_LOCKID;
                    }
                    if(DealRecData[5]==0x10)
                    {
                        return BatLowValueWrite;
                    }
                }
            }
        }
    }


    //载荷长度为7的命令
    if(DealRecData[0]==0x7B&&DealRecData[10]==0x7D&&DealRecData[1]==0x07)
    {
        reccs=0;

        for(i=2; i<9; i++)
        {
            reccs=reccs+DealRecData[i];
        }
        if(reccs==DealRecData[9])
        {
            if((DealRecData[2]==ID_LOCK[0]&&DealRecData[3]==ID_LOCK[1])||(DealRecData[2]==0xFF&&DealRecData[3]==0xFF))
            {
                if(DealRecData[4]==0x06)
                {
                    switch (DealRecData[5])
                    {
                      case 0x05:
                        return ADDED_WL_LOCK;
                      case 0x07:
                        {
                          memcpy(SystemPara.PcID,&DealRecData[6],3*sizeof(uint8_t));
                          return ADDED_WL_PC;
                        }
                      default:
                        break;
                    }
                }
            }
        }
    }

    //载荷长度为8
    if(DealRecData[0]==0x7B&&DealRecData[11]==0x7D&&DealRecData[1]==0x08)
    {
        reccs=0;

        for(i=2; i<10; i++)
        {
            reccs=reccs+DealRecData[i];
        }

        if(reccs==DealRecData[10])
        {
            if((DealRecData[2]==ID_LOCK[0]&&DealRecData[3]==ID_LOCK[1])||(DealRecData[2]==0xFF&&DealRecData[3]==0xFF))
            {
                if(DealRecData[4]==0x06)
                {
                    if(DealRecData[5]==0x08)
                    {
                        
                        memcpy(CarRecDataStr.Opa,&DealRecData[6],4*sizeof(uint8_t)); 
                        memcpy(SystemPara.QmcFixPara,&DealRecData[6],4*sizeof(uint8_t)); 
                        return OPT_CONF;
                    }
                    if(DealRecData[5]==0x0B)
                    {
                        return SET_CURRENT_PARA;
                    }
                }

            }
        }
    }

    if(DealRecData[0]==0x7B&&DealRecData[17]==0x7D&&DealRecData[1]==0xF0)
    {
        reccs=0;

        for(i=2; i<16; i++)
        {
            reccs=reccs+DealRecData[i];
        }
        if(reccs==DealRecData[16])
        {
            if((DealRecData[2]==ID_LOCK[0]&&DealRecData[3]==ID_LOCK[1])||(DealRecData[2]==0xFF&&DealRecData[3]==0xFF))
            {
                return SET_PHO_PARA;//修改光敏阈值
            }
        }
    }

    //载荷长度为10
    if(DealRecData[0]==0x7b&&DealRecData[13]==0x7d&&DealRecData[1]==0x0a)
    {
        reccs=0;
        for(i=2; i<12; i++)
        {
            reccs=reccs+DealRecData[i];
        }
        if((DealRecData[2]==ID_LOCK[0]&&DealRecData[3]==ID_LOCK[1])||(DealRecData[2]==0xFF&&DealRecData[3]==0xFF))
        {
            if(DealRecData[4]==0x06&&DealRecData[5]==0x0D)
            {
                return SET_WL_PARA;
            }
        }
    }
    return ERR;

}

void CmdDeal(void)
{
    uint8_t CMD;
    CMD = SingalCheck();
    switch(CMD)
    {
      case PC_OPEN:
        {
            SendData(CMD);
            CarAction(1,0,1,2);
            break;
        }
      case PC_CLOSE:
        {
            SendData(CMD);
            CarAction(1,0,1,1);
            break;
        }
      case ALL_OPEN:
        {
            SendData(CMD);
            CarAction(0,0,1,2);
            bsp_beep_one();
            break;
        }
      case ALL_CLOSE:
        {
            SendData(CMD);
            CarAction(0,0,1,1);
            bsp_beep_one();
            break;
        }
      case SET_CAR_YES_STATE:
        {
            SendData(CMD);
            CarRecDataStr.CarState = 1;
            bsp_beep_one();
            break;
        }
      case SET_CAR_NO_STATE:
        {
            SendData(CMD);
            CarRecDataStr.CarState = 0;
            bsp_beep_one();
            break;
        }
      case PC_REQ:
        {
            BatVolDec(1);
            SendData(CMD);
            bsp_beep_one();
            break;
        }
      case GET_OPT_PA:
        {
            SendData(CMD);
            bsp_beep_one();
            break;
        }
      case ADDED_LOCKID:
        {
            SendData(CMD);
            bsp_beep_one();
            break;
        }

      case ADDED_WL_LOCK:
        {
            SendData(CMD);
            bsp_beep_one();
            break;
        }
      case ADDED_WL_PC:
        {
            FixedParaChange(TRUE);
            SendData(CMD);
            bsp_beep_one();
            break;
        }
      case OPT_CONF:
        {
            FixedParaChange(TRUE);
            SendData(CMD);
            bsp_beep_one();
            break;
        }
      case SET_WL_PARA:
        {
            SendData(CMD);
            bsp_beep_one();
            break;
        }
      case SET_BEEP_0:
        {
            BeepStart(3,0);
            SendData(CMD);
        }
      default :break;
    }
}

void SendData(u8 SINGAL)
{
	struct WIRELESS_STR sendstr={0};
	uint8_t *temp = &sendstr.Data[0];
	if(CarRecDataStr.ForKingView++>254)
	{
		CarRecDataStr.ForKingView=0;
	}
	//回传数据包的公共部分
		memcpy(sendstr.WireId,SystemPara.PcID,3*sizeof(uint8_t));
                memcpy(CarRecDataStr.Opa,SystemPara.QmcFixPara,4*sizeof(uint8_t));
		sendstr.FrameHead = 0X7B;
		sendstr.FrameTail = 0x7D;
		memcpy(sendstr.LockId,SystemPara.LockID,2*sizeof(uint8_t));
                memcpy(CarRecDataStr.hmcX,QMC5883LStr.QMC_CUR_ROPORT,2*sizeof(uint8_t));
                get_photoresistor_ad();
                CarRecDataStr.hmcX[0] = QMC5883LStr.QMC_CUR_ROPORT[1];
                CarRecDataStr.hmcX[1] = QMC5883LStr.QMC_CUR_ROPORT[0];
                CarRecDataStr.hmcY[0] = QMC5883LStr.QMC_CUR_ROPORT[5];
                CarRecDataStr.hmcY[1] = QMC5883LStr.QMC_CUR_ROPORT[4];
                CarRecDataStr.pr[0] = VAL_PHOTO>>8;
                CarRecDataStr.pr[1] = VAL_PHOTO;
                //memcpy(CarRecDataStr.hmcY,&QMC5883LStr.QMC_CUR_ROPORT[4],2*sizeof(uint8_t)); 
                #define DiodeDrop (0.15/3.3*4096*10/308)
                CarRecDataStr.Voltage = (u8)(BatVoltage[0]+DiodeDrop);
                  
        /***********************************************/
	if(SINGAL==PC_CLOSE||SINGAL==PC_OPEN)   //网关发送开启和关闭的命令。返回当前位置和电池电量以及自增
	{
                CarRecDataStr.CmdSource = 1;
		sendstr.CmdLength = 0X10;
		*temp++ = 0x10;
		*temp++ = 0XFF;
		*temp++ = CarRecDataStr.LockState;
		*temp++ = CarRecDataStr.AlarmFlag;
		*temp++ = CarRecDataStr.Voltage;
		*temp++ = CarRecDataStr.CmdSource; //命令来源
		memcpy(temp,CarRecDataStr.hmcX,6*sizeof(uint8_t));
		temp = temp + 6;
		*temp++ = CarRecDataStr.CarState;
		*temp++ = CarRecDataStr.ForKingView;//自增码

	}
        else if(SINGAL==PC_OPEN_REPORT||SINGAL==PC_CLOSE_REPROT)//车位锁动作后主动上报，待收到网关后停止上报
        {
                        CarRecDataStr.CmdSource = 0;
			sendstr.CmdLength = 0X10;
			*temp++ = 0x0A;
			*temp++ = 0XFF;
			*temp++ = CarRecDataStr.LockState;
			*temp++ = CarRecDataStr.AlarmFlag;
			*temp++ = CarRecDataStr.Voltage;
			*temp++ = CarRecDataStr.CmdSource; //命令来源
			memcpy(temp,CarRecDataStr.hmcX,6*sizeof(uint8_t));
			temp = temp + 6;
			*temp++ = CarRecDataStr.CarState;
			*temp++ = CarRecDataStr.ForKingView;//自增码
        }
	else if(SINGAL==PC_REQ) //参数查询
	{
                        static uint32_t tempq = 0;

                        tempq = SystemPara.SoftVersion[0]*1000000;
                        tempq+= SystemPara.SoftVersion[1]*100000;
                        tempq+= SystemPara.SoftVersion[2]*10000;
                        tempq+= SystemPara.SoftVersion[3]*1000;
                        tempq+= SystemPara.HardVersion[1]*100;
                        tempq+= SystemPara.HardVersion[2]*10;
                        tempq+= SystemPara.HardVersion[3]*1;
                
                        CarRecDataStr.CmdSource = 1;
			sendstr.CmdLength = 0X10+3;
			*temp++ = 0x08;
			*temp++ = 0XFF;
			*temp++ = CarRecDataStr.LockState;
			*temp++ = CarRecDataStr.AlarmFlag;
			*temp++ = CarRecDataStr.Voltage;
			*temp++ = CarRecDataStr.CmdSource; //命令来源
			memcpy(temp,CarRecDataStr.hmcX,6*sizeof(uint8_t));
			temp = temp + 6;
			*temp++ = CarRecDataStr.CarState;
			*temp++ = CarRecDataStr.ForKingView;//自增码
                        *temp++ = (tempq&0xFF0000)>>16;
                        *temp++ = (tempq&0x00FF00)>>8;
                        *temp++ = tempq;
                        
	}
	else if(SINGAL==ADDED_LOCKID)
	{

		sendstr.CmdLength = 0X06;
		*temp++ = 0X10;
		*temp++ = 0X00;
		memcpy(temp,SystemPara.LockID,2*sizeof(uint8_t));
		*(temp + 2) = CarRecDataStr.ForKingView;
	}
        else if(SINGAL==ADDED_WL_PC)
        {
                sendstr.CmdLength = 0X07;
		*temp++ = 0X10;
		*temp++ = 0X07;
		memcpy(temp,SystemPara.PcID,3*sizeof(uint8_t));
		*(temp + 3) = CarRecDataStr.ForKingView;
        }
	else if(SINGAL==OPT_CONF)
	{
		sendstr.CmdLength = 0X08;
		*temp++ = 0X10;
		*temp++ = 0X08;
		memcpy(temp,CarRecDataStr.Opa,4*sizeof(uint8_t));
		*(temp + 4) = CarRecDataStr.ForKingView;
	}
	else if(SINGAL==GET_OPT_PA)
	{
		sendstr.CmdLength = 0X08;
		*temp++ = 0X08;
		*temp++ = 0X08;
		memcpy(temp,CarRecDataStr.Opa,4*sizeof(uint8_t));
		*(temp + 4) = CarRecDataStr.ForKingView;
	}
	else if(SINGAL==GET_ADDED_WL_PC)
	{
		sendstr.CmdLength = 0X07;
		*temp++ = 0X08;
		*temp++ = 0X07;
		memcpy(temp,SystemPara.PcID,3*sizeof(uint8_t));
		*(temp + 3) = CarRecDataStr.ForKingView;
	}
	else if(SINGAL==PC_OPEN_FAULT)
	{
			sendstr.CmdLength = 0X10;
			*temp++ = 0x04;
			*temp++ = 0XFF;
			*temp++ = 0x10;
//			*temp++ = CarRecDataStr.LockState;
			*temp++ = CarRecDataStr.AlarmFlag;
			*temp++ = CarRecDataStr.Voltage;
			*temp++ = CarRecDataStr.CmdSource; //命令来源
			memcpy(temp,CarRecDataStr.hmcX,6*sizeof(uint8_t));
			temp = temp + 6;
			*temp++ = CarRecDataStr.CarState;
			*temp++ = CarRecDataStr.ForKingView;//自增码
	}
	else if(SINGAL==PC_CLOSE_FAULT)
	{
			sendstr.CmdLength = 0X10;
			*temp++ = 0x04;
			*temp++ = 0XFF;
			*temp++ = 0x11;
//			*temp++ = CarRecDataStr.LockState;
			*temp++ = CarRecDataStr.AlarmFlag;
			*temp++ = CarRecDataStr.Voltage;
			*temp++ = CarRecDataStr.CmdSource; //命令来源
			memcpy(temp,CarRecDataStr.hmcX,6*sizeof(uint8_t));
			temp = temp + 6;
			*temp++ = CarRecDataStr.CarState;
			*temp++ = CarRecDataStr.ForKingView;//自增码
	}
	else if(SINGAL==ALARM)
	{
			sendstr.CmdLength = 0X10;
			*temp++ = 0x04;
			*temp++ = 0XFF;
			*temp++ = CarRecDataStr.LockState;
			*temp++ = CarRecDataStr.AlarmFlag;
			*temp++ = CarRecDataStr.Voltage;
			*temp++ = CarRecDataStr.CmdSource; //命令来源
			memcpy(temp,CarRecDataStr.hmcX,6*sizeof(uint8_t));
			temp = temp + 6;
			*temp++ = CarRecDataStr.CarState;
			*temp++ = CarRecDataStr.ForKingView;//自增码
                        CarRecDataStr.AlarmFlag = 0; 
	}
	else if(SINGAL==HAVE_CAR)
	{
			sendstr.CmdLength = 0X10;
			*temp++ = 0x04;
			*temp++ = 0XFF;
			*temp++ = CarRecDataStr.LockState;
			*temp++ = CarRecDataStr.AlarmFlag;
			*temp++ = CarRecDataStr.Voltage;
			*temp++ = CarRecDataStr.CmdSource; //命令来源
			memcpy(temp,CarRecDataStr.hmcX,6*sizeof(uint8_t));
			temp = temp + 6;
			*temp++ = CarRecDataStr.CarState;
			*temp++ = CarRecDataStr.ForKingView;//自增码
	}
	else if(SINGAL==SET_BEEP_0)
	{                       
			sendstr.CmdLength = 0X05;
			*temp++ = 0x10;
			*temp++ = 0X09;
			*temp++ = 0;
			*temp++ = CarRecDataStr.ForKingView;
	}
	else if(SINGAL==SET_CAR_NO_STATE)
	{
			sendstr.CmdLength = 0X05;
			*temp++ = 0x10;
			*temp++ = 0X0E;
			*temp++ = 0;
			*temp++ = CarRecDataStr.ForKingView;
	}
	else if(SINGAL==SET_CAR_YES_STATE)
	{
			sendstr.CmdLength = 0X05;
			*temp++ = 0x10;
			*temp++ = 0X0E;
			*temp++ = 1;
			*temp++ = CarRecDataStr.ForKingView;
	}
        else
        {
          return;
        }
	//公共部分
        int i = 0;
	temp = &sendstr.LockId[0];
	for(i=0;i<sendstr.CmdLength;i++)
	{
		sendstr.CheckSum += *temp++;
	}
	SX78Str.SX7xTxFlag = TRUE;
	SX78Str.SX7xCmd = CmdTX;
        SX78Str.SX7xTxlen = (sendstr.CmdLength + 3 + 1 + 1 + 1 +1);
	memcpy(SX78Str.SX7xTxStr,sendstr.WireId,SX78Str.SX7xTxlen-2);
        SX78Str.SX7xTxStr[SX78Str.SX7xTxlen -2] = sendstr.CheckSum;
	SX78Str.SX7xTxStr[SX78Str.SX7xTxlen -1] = 0x7D;
        asm("NOP;");
}

void CycleDetection(void)
{
      if(CycleDetectionTime)return;
      CycleDetectionTime = 10;
      if(LIMIT_READ)CarRecDataStr.LockState = 1;
      else
        CarRecDataStr.LockState = 0;
      if(QMC5883LStr.DataOkFlag == 0)return;
      if(LockCarState.HostReportDelay)return;
      if((LockCarState.HostReportFlag==1)&&(LockCarState.MotorCmd==CmdIdle))
      {
          LockCarState.HostReportFlag = 0;
          if((LockCarState.MotorActResults == RISE_OK)||(LockCarState.MotorActResults == FALL_OK))
          {
              CarRecDataStr.CarState = 0;
              SendData(PC_OPEN_REPORT);
              if(LockCarState.MotorActResults == FALL_OK)
              {
                  mag_time_count = 0;
                  QMC5883LStr.DataOkFlag = 0;
                  //memcpy(QMC5883LStr.QMC_BASE,QMC5883LStr.QMC_CUR,3*sizeof(int16_t));
                  //BeepStart(1,0);
              }
          }
          if(LockCarState.MotorActResults == RISE_ERROR)
          {

              CarRecDataStr.CarState = 1;
              SendData(PC_CLOSE_FAULT);
          }
          if(LockCarState.MotorActResults == FALL_ERROR)
          {
              SendData(PC_OPEN_FAULT);
          }
      }
      else if((NoCarDealReportFlag==TRUE)&&(LockCarState.MotorCmd==CmdIdle))
      {
          NoCarDealReportFlag = FALSE;
          if(LockCarState.MotorActResults==RISE_ERROR)
          {       
              memcpy(QMC5883LStr.QMC_STABLE,QMC5883LStr.QMC_CUR,3*sizeof(int16_t));
              get_photoresistor_ad();
              ph_stable_value = VAL_PHOTO;
              CarRecDataStr.CarState = 1;
              CarRecDataStr.CmdSource = 1;    
              SendData(PC_CLOSE_FAULT);
          }
          else
          {
              CarRecDataStr.CarState = 0;
              CarRecDataStr.CmdSource = 2;  
              SendData(HAVE_CAR);
          }
      }
      if((LockCarState.MotorActResults == RISE_OK)||(LockCarState.MotorActResults == FALL_ERROR))
      {
          static uint8_t temp = 0;
          mag_time_count = 0;
          if((CarRecDataStr.LockState == 0)&&(temp==0)&&(LockCarState.MotorCmd==CmdIdle))
          {
            temp = 1;
            CarRecDataStr.AlarmFlag = 1;
            SendData(ALARM);
            BeepStart(5,1);
          }
          else if(CarRecDataStr.LockState == 1)
          {
            if(UserBeep.Model==1)BeepStop();
            temp = 0;
          }
      }
      
//      if((tempFlag==TRUE)&&(LockCarState.MotorActResults == RISE_OK))
//      {
//          tempFlag = FALSE;
//          CarRecDataStr.CarState = 0;
//          CarRecDataStr.CmdSource = 2;     
//          SendData(HAVE_CAR);
//      }

}


