#include "bsp.h"
#include "wdg.h"
#include "timer.h"
#include "usart.h"
#include "led.h"
#include "key.h"
#include "esp8266.h"
#include "connect.h"
#include "pro_phy.h"
#include "md5.h"
//#include "aes.h"

time_obj run_time;//定义时间结构体变量
extern void USART1_RecvData(void);
//系统初始化
void BspInit(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断组为2,NVIC中断分组2:2位抢占优先级,2位响应优先级(0-3)

	IWDG_Init();
	TIMER_Init();
	TIM_Delay_Init();
	LED_Init();
	KEY_Init();
	UART1_Init(115200);//调试
	UART2_Init(115200);//ESP8266
	Connect_Init();//ESP8266
	NRF_Init();//初始化协议
	MemSet((BYTE *)&run_time,0,sizeof(time_obj));//初始化结构体变量
}

void Idle(void)
{
	u32 main_time=Get_RunTime();
	
	IWDG_Feed();//喂狗
	Key_Scan();
	USART1_RecvData();
	if (IS_TIMEOUT_10MS(eTimNrf, 1)&&!NRF_GetThreadLockState())//10ms
	{
		NRF_Thread();//定时线程,执行协议
	}
	if(main_time-run_time.time>=100)//间隔1秒
	{
		run_time.time=main_time;
		run_time.sec++;
		if(run_time.sec>=60)
		{
			run_time.sec=0;
			run_time.min++;
			if(run_time.min>=60)
			{
				run_time.min=0;
				run_time.hour++;
				if(run_time.hour>=24)
				{
					run_time.hour=0;
					run_time.date++;
				}
			}
		}
	}
}

u8 Get_Nid(const u8 val)
{
	char up_id[3]={0};
	char up_id2[1]={0};
	u8 up_nid;
	
	sprintf(up_id,"%d",val);
	if(val<100)//计算nid
	{
		up_id2[0]=up_id[1];//2位
		up_nid=atoi(up_id2);
	}
	else
	{
		up_id2[0]=up_id[2];//3位
		up_nid=atoi(up_id2);
	}
	return up_nid;
}

void GetBody(char *dststr,char *srcstr)//获取只是{xxxxxx}的字符
{
	char buff[PAYLOAD_DATA_LEN];
	u16 i,num=0;
	u8 flag=0;

	for(i=0;i<strlen(srcstr);i++)
	{
		if(srcstr[i]=='{')
		{
			flag=1;
		}
		if(flag)
		{
			buff[num++]=srcstr[i];
		}
		if(srcstr[i]=='}'||num>=PAYLOAD_DATA_LEN)
		{
			flag=0;
			break;
		}
	}
	sprintf(dststr,"%s",buff);
}

u16 GetNumber(char *srcstr,u8 start,u8 byte)//从{xxxxxx}中获取num
{
	char buff[10];
	
	if(strstr(srcstr,"{")&&strstr(srcstr,"}")&&strlen(srcstr)>10)
	{
		memcpy(buff,srcstr+start,byte);
		return strtol(buff,NULL,10);
	}
	else 
	{
		return 0;
	}
}

//从str中得到参数//srcstr:字符串;str:标识符
u32 GetValue(char *srcstr,char *str)	
{	
	while(*srcstr!=*str)//偏移到参数开始的地方
	{
		srcstr++;	
		if(*srcstr=='\0')
			return 0;//遇到结束符了
	}
	srcstr++;
	//return atoi(srcstr);	
	return strtol(srcstr,NULL,10);
}

//srcstr字符串;str标识符;返回值:长度; 0,错误
u8 GetDataLength(char *srcstr,char *str)//xxxxx,xxx//长度=5
{
	u8 len=0;
	
	while(*srcstr!=*str)//偏移到参数开始的地方
	{
		srcstr++;	
		len++;
	}
	return len;
}

//str:标识符
void CopyString(char *dststr,char *srcstr,char *str)
{
	u8 len=0;
	
	while(1)
	{										   
		if(*srcstr=='\0'||*srcstr=='\r'||*srcstr=='\n'||*srcstr==*str)
		{
			*dststr='\0';
			return;//拷贝完成了.
		}
		*dststr=*srcstr;//拷贝
		srcstr++;
		dststr++;
		len++;
		if(len>=PAYLOAD_DATA_LEN-1)
		{
			return;
		}
	}
}

void PrintAddr(char *str,u8 *addr)
{
	u8 i;

	printf("%s:",str);
	for(i=0;i<MAC_LEN;i++)
	{
		printf("%02x ",addr[i]);
	}
	printf("\r\n");
}

void PrintHex(u8 *buf,u16 len)
{
	u16 i;
	printf("\r\n");
	for(i=0;i<len;i++)
	{
		printf("%02x ",buf[i]);
	}
	printf("\r\n\r\n");
}

//crc单字节效验//方程式为X＾8＋X＾2＋X＋1
u8 cal_crc8(u8 *ptr, u8 len) 
{
	u8 i,crc=0;
	
	while(len--!=0) 
	{
		for(i=0x80; i!=0; i/=2)
		{
			if((crc&0x80)!=0) 
			{
				crc*=2; 
				crc^=0x07;//余式CRC乘以2再求CRC
			}
			else 
				crc*=2;
			if((*ptr&i)!=0) 
				crc^=0x07;//再加上本位的CRC
		}
		ptr++;
	}
	return(crc);
}

u16 cal_crc16(u8 *pData, u16 sLen)
{  
   u16 i,crc = 0;
   
   while(sLen--)  //len是所要计算的长度
   {
       crc = crc^(int)(*pData++) << 8;
       for (i=8; i!=0; i--) 
       {
           if (crc & 0x8000)   
               crc = crc << 1 ^ 0x1021;    
           else
               crc = crc << 1;
       }    
   }
   return crc;
}

//u32 cal_crc32(u32 *ptr, u16 len)
//{
//	u32 crc=0xFFFFFFFF;
//	u16 i,k;

//    for(k=0;k<len;k++)
//    {
//        crc = crc ^ (*ptr++);
//        for (i = 0; i < 32; i++)
//        {
//            if (crc & 0x80000000)
//                crc = (crc << 1) ^ 0x04c11db7;
//            else
//                crc <<= 1;
//        }
//        crc &= 0xFFFFFFFF;
//    }
//    return(crc);
//}

//STM32硬件CRC32 byte数据计算,将数据移到最高位,低位补上FF  
u32 stm32_crc32_byte(u8 *pBuff, u32 len)  
{  
    u32 i;  
    u8 buff[4];  
    u32 *p32 = (u32 *)buff;  
      
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);//打开CRC硬件时钟
    CRC->CR = 1; //复位CRC寄存器  
    buff[0] = buff[1] = buff[2] = buff[3] = 0XFF;  
    for(i = 0;i < len;i ++)  
    {  
        buff[3] = pBuff[i];  
        CRC->DR = *p32;  
    }  
    return CRC->DR;  
}  

//STM32硬件CRC32 u32数据计算  
u32 stm32_crc32(u32 *pBuff, u32 len)  
{  
    u32 i;  
  
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);//打开CRC硬件时钟
    CRC->CR = 1; //复位CRC寄存器  
    for(i = 0;i < len;i ++)  
    {  
        CRC->DR = pBuff[i];  
    }  
    return CRC->DR;  
}  
  
//软件CRC32 u32数据计算  
u32 crc32(u32 *ptr, u32 len)  
{  
    u32 CRC32=0xFFFFFFFF;  
    u32 xbit,data,bits,i;  
    const u32 dwPolynomial = 0x04c11db7;  
      
    for(i = 0;i < len;i ++)  
    {  
        xbit = (u32)1 << 31;  
        data = ptr[i];  
        for (bits = 0; bits < 32; bits++)   
        {  
            if (CRC32 & 0x80000000) {  
                CRC32 <<= 1;  
                CRC32 ^= dwPolynomial;  
            }  
            else  
                CRC32 <<= 1;  
            if (data & xbit)  
                CRC32 ^= dwPolynomial;  
  
            xbit >>= 1;  
        }  
    }  
    return CRC32;  
}  

//软件CRC32 byte数据计算,将数据移到最高位,低位补上FF  
u32 crc32_byte(u8 *ptr, u32 len)  
{  
    u32 CRC32=0xFFFFFFFF;//初值  
    u32 xbit,bits,data,i;  
    u8 buff[4];  
    u32 *p32 = (u32 *)buff;  
    const u32 dwPolynomial = 0x04c11db7;  
      
    buff[0] = buff[1] = buff[2] = buff[3] = 0XFF;  
    for(i = 0;i < len;i ++)  
    {   
		xbit = (u32)1 << 31;
        buff[3] = ptr[i];  
        data = *p32;  
        for(bits = 0; bits < 32; bits++)   
        {  
            if (CRC32 & 0x80000000) 
			{  
                CRC32 <<= 1;  
                CRC32 ^= dwPolynomial;  
            }  
            else  
                CRC32 <<= 1;  
            if (data & xbit)  
                CRC32 ^= dwPolynomial;  
  
            xbit >>= 1;  
        }  
    }  
    return CRC32;  
}

//void Get_ChipID(u32* ChipID)
//{
//	ChipID[0] = *(__IO u32 *)(0x1FFFF7E8);
//	ChipID[1] = *(__IO u32 *)(0x1FFFF7EC);
//	ChipID[2] = *(__IO u32 *)(0x1FFFF7F0);
//}

u32 Get_NetworkID(void)
{
	u32 addr=0x1FFFF7E8;
//	u16 val1,val2;
	u8 ChipID[12]={0};//用以存贮96位ID号
	u8 key[16]={0};
//	u8 tmp[8]={0};
	u8 i;
	
	for(i=0;i<12;i++)//获取芯片ID
	{
		ChipID[i] = *((__IO u32 *)addr++);
	}
	MD5_String(key,(char *)ChipID);
	for(i=0;i<16;i++)//异或加密
	{
		 key[i] ^= 0x22;
	}
//	for(i=0;i<8;i++)
//	{
//		tmp[i] = key[i];
//	}
//	MD5_String(key,(char *)tmp);
//	val1=cal_crc16(key, 16);
//	for(i=0;i<8;i++)
//	{
//		tmp[i] = key[i+8];
//	}
//	MD5_String(key,(char *)tmp);
//	val2=cal_crc16(key, 16);
//	sprintf((char *)key,"%05d%05d}",val1,val2);
//	return strtol((char *)key,NULL,10);
//	return cal_crc32(key,16);
	return crc32_byte(key,16);
}

void MemSet(BYTE *p,BYTE val,u32 length)
{
	u32 i=0;
	for(i=0;i<length;i++)
	{
		p[i]=val;
	}
}

void MemCopy(BYTE *dst,BYTE *src,u32 length)
{
	u32 i=0;
	for(i=0;i<length;i++)
	{
		dst[i]=src[i];
	}
}

void NRF_CopyMac(u8 *dstMac,const u8 *srcMac)
{
	u8 i=0;
	for(i=0;i<MAC_LEN;i++)
	{
		dstMac[i]=srcMac[i];
	}
}

BOOL NRF_CmpMac(const u8 *dstMac,const u8 *srcMac)
{
	u8 i=0;
	for(i=0;i<MAC_LEN;i++)
	{
		if(dstMac[i]!=srcMac[i])
		{
			return FALSE;
		}
	}
	return TRUE;
}

//冒泡排序
void BubbleSort(u8 *arr, u16 size)
{ 
	u16 i=0,j=0, k=size-1,pos=0;//pos变量用来标记循环里最后一次交换的位置    

	for(i=0;i<size-1;i++)//一共要排序size-1次  
	{  
		//每次遍历标志位都要先置为0，才能判断后面的元素是否发生了交换  
		u8 flag=0;  

		for(j=0;j<k;j++)//选出该趟排序的最大值往后移动
		{  
			//if(arr[j]>arr[j+1])//从小到大
			if(arr[j]<arr[j+1])//从大到小
			{
				u8 tmp=arr[j];
				arr[j]=arr[j+1];
				arr[j+1]=tmp;
				flag=1;//只要有发生了交换，flag就置为1
				pos=j;//循环里最后一次交换的位置j赋给pos
			}
		}
		k=pos;
		//判断标志位是否为0，如果为0，说明后面的元素已经有序，就直接return
		if(flag==0)
		{
			return;
		}
	}
}
