
/**
  ******************************************************************************
  * @file    BLV_485_Dev_WeixinLockFun.c
  * @author  BLW RCU  development Team
  * @version V1.0.0
  * @date    2021年11月02日
  * @brief   微信锁驱动总表         可以控制开锁关锁，以及得到锁的状态
	* @log     202205260850   SongHan   锁的波特率以传过来的参数为准
	* 
  ******************************************************************************
	2022.07.14			林开锐
		在BLV_485_Dev_WeixinLockFun.h微信锁私有数据RS485_WxLock_INFO结构体中添加创佳微信锁定义
  ******************************************************************************
  */

#include "includes.h"  

#include "BLV_485_Dev_WeixinLockFun.h"
#include "string.h"

/*外设头文件开始*/
#include "BLV_485_Dev_BLWLockFun.h"
#include "BLV_485_Dev_FreegoLockFun.h"
#include "BLV_485_Dev_ChuangJiaLockFun.h"
#include "BLV_485_Dev_YangGeLockFun.h"
/*外设头文件结束*/

#define RFLOCKCYCLEWAITTIMEOUT       5000    //无线锁轮询超时等待时间    控制结束后便进入轮询
/*函数指针宏定义*/
typedef void (*DevFunP)(Device_Public_Information_G *BUS_Public, RS485_WxLock_INFO *Rs485WxLockInfo);	//传递共用数据指针 私有数据指针

/*设备驱动宏定义开始*/
#define RS485_DEV_PRO_FUN_01    DevExistJudgge(RS485_WxLock_BLW_Flag, BLW_RS485_WxLockFun_Init)//((DevFunP)NULL)      //宝来威微信锁
#define RS485_DEV_PRO_FUN_02    DevExistJudgge(RS485_WxLock_FreeGo_Flag, Freego_RS485_WxLockFun_Init)   //((DevFunP)NULL) 福瑞狗微信锁 
#define RS485_DEV_PRO_FUN_03    DevExistJudgge(RS485_WxLock_CJia_Flag, ChuangJia_RS485_WxLockFun_Init)  //((DevFunP)NULL)      //创佳微信锁
#define RS485_DEV_PRO_FUN_04    DevExistJudgge(RS485_WxLock_YangGe_Flag, YangGe_RS485_WxLockFun_Init)  //((DevFunP)NULL)      //杨格微信锁
//#define RS485_DEV_PRO_FUN_04    ((DevFunP)NULL)      
#define RS485_DEV_PRO_FUN_05    ((DevFunP)NULL)  
/*设备驱动宏定义结束*/


void RF_Rs485_WxLock_Pro(uint8_t *Data, CFG_Dev_AddP CfgDevAdd);

uint8_t RF_Rs485_WxLock_CtrlCycle(uint32_t dev_addr); 
uint8_t RF_WxLock_Read(uint32_t dev_addr,uint32_t data_addr,uint16_t len);
void RF_WxLock_TimeSet(uint32_t dev_addr, uint32_t RfGatewayHostAddr);
void RF_WxLock_Ctrl(CFG_Dev_AddP CfgDevAdd, RS485_WxLock_INFOP Rs485WxLockInfo,uint32_t dev_addr);
void RFDevRecAsk(uint32_t RfGatewayHostAddr, CFG_Dev_AddP CfgDevAdd, uint8_t DevType);

/*******************************************************************************
* @name  :  延时设备处理函数
* @para  : 
*		devaddr	:设备485地址
*   DataLen :数据长度
*   Data：   数据数组
* @attention   : 将调光的所有设备参数传进来，
*
*******************************************************************************/
void BLW_RS485_WeixinLockFun_Init(uint16_t DataLen, uint8_t *Data)
{
	Device_Public_Information_G BUS_Public;
	RS485_WxLock_INFO Rs485WxLockInfo;

	memset(&BUS_Public,0,sizeof(Device_Public_Information_G));
	memset(&Rs485WxLockInfo,0,sizeof(RS485_WxLock_INFO));
	
	BUS_Public.addr = Data[1];		//设备485地址
	BUS_Public.type = Data[0];		//设备类型
	BUS_Public.baud = Data[3] + (Data[4]<<8) + (Data[5]<<16) + (Data[6]<<24);		    //设备发送波特率
	BUS_Public.retry_num = 0x03;	//设备数据重发次数
	BUS_Public.wait_time = 0x00C8;	//设备数据发送等待回复时间 - 200ms
//	BUS_Public.polling_cf = (uint32_t)&BLW_LEDCycleCtrl;          //以实际驱动为准
//	BUS_Public.processing_cf = (uint32_t)&BLW_Rs485_LED_Check;    //以实际驱动为准
	
	BUS_Public.DevFunInfo.Dev_Output_Ctrl = RS485_WxLock_IndiCtrl;   
//	BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get = NULL;   
	
	Rs485WxLockInfo.DevOffline = Rs485WxLockInfo.DevOfflineLast = DEV_IS_LINEUNINIT;   //在线状态初始化
	switch(Data[7])
	{
		case	 ENUM_RS485_DEV_PRO_01: if(NULL!=RS485_DEV_PRO_FUN_01) RS485_DEV_PRO_FUN_01(&BUS_Public, &Rs485WxLockInfo);break; //        
		case	 ENUM_RS485_DEV_PRO_02: if(NULL!=RS485_DEV_PRO_FUN_02) RS485_DEV_PRO_FUN_02(&BUS_Public, &Rs485WxLockInfo);break; //          
		case	 ENUM_RS485_DEV_PRO_03: if(NULL!=RS485_DEV_PRO_FUN_03) RS485_DEV_PRO_FUN_03(&BUS_Public, &Rs485WxLockInfo);break;                                 //3
		case	 ENUM_RS485_DEV_PRO_04: 
			if(NULL!=RS485_DEV_PRO_FUN_04) {
				
				Rs485WxLockInfo.YG_IdVldPeriod = 300000;       //默认身份有效期,5min
				if(Data[23] == 0x01){                           //秒
					Rs485WxLockInfo.YG_IdVldPeriod = (Data[24]*1000);
				}else if(Data[23] == 0x02){                     //分
					Rs485WxLockInfo.YG_IdVldPeriod = (Data[24]*60*1000);
				}
				
				RS485_DEV_PRO_FUN_04(&BUS_Public, &Rs485WxLockInfo);
			}
			break;
        case	 ENUM_RS485_DEV_PRO_05: if(NULL!=RS485_DEV_PRO_FUN_05) RS485_DEV_PRO_FUN_05(&BUS_Public, &Rs485WxLockInfo);break;
	}
	DevActionGlobal.Lock485Addr = BUS_Public.addr; 

	switch(Data[2])
	{
		case Active_Port:   //主动端口
			BUS_Public.port = Active_Port;		//设备发送端口
			Add_ACT_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485WxLockInfo,sizeof(RS485_WxLock_INFO));
		  Act485_Info.baud = BUS_Public.baud;  //波特率赋值
			Dbg_Println(DBG_BIT_DEVICE_STATUS_bit,"主动总线波特率赋值:%d", Act485_Info.baud);
		  Act485_Info.device_num += 1;
			break;  
		case Polling_Port:   //轮询端口
			BUS_Public.port = Polling_Port;		//设备发送端口
			Add_POLL_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485WxLockInfo,sizeof(RS485_WxLock_INFO));   //将填充后的数据添加到链表
			Poll485_Info.device_num += 1;	
			break;
		case Bus_port:    //总线端口
			break;
	}

}


/*******************************************************************************
* @name  :  延时设备处理函数
* @para  : 
*		devaddr	:设备485地址
*   DataLen :数据长度
*   Data：   数据数组
* @attention   : 将调光的所有设备参数传进来，
*
*******************************************************************************/
void BLW_RS485_WeixinLockFun_Logic_Init(LOGICFILE_DEVICE_INFO *dev_info,uint8_t *data,uint16_t data_len)
{
	Device_Public_Information_G BUS_Public;
	RS485_WxLock_INFO Rs485WxLockInfo;

	memset(&BUS_Public,0,sizeof(Device_Public_Information_G));
	memset(&Rs485WxLockInfo,0,sizeof(RS485_WxLock_INFO));
	
	BUS_Public.addr = dev_info->addr;		//设备485地址
	BUS_Public.type = dev_info->type;		//设备类型
	BUS_Public.baud = dev_info->baud;		//设备发送波特率
	BUS_Public.retry_num = 0x03;	//设备数据重发次数
	BUS_Public.wait_time = 0x00C8;	//设备数据发送等待回复时间 - 200ms
	BUS_Public.Protocol = dev_info->version;
//	BUS_Public.polling_cf = (uint32_t)&BLW_LEDCycleCtrl;          //以实际驱动为准
//	BUS_Public.processing_cf = (uint32_t)&BLW_Rs485_LED_Check;    //以实际驱动为准
	
	BUS_Public.DevFunInfo.Dev_Output_Ctrl = RS485_WxLock_IndiCtrl;   
//	BUS_Public.DevFunInfo.Dev_Output_Loop_State_Get = NULL;   
	
	Rs485WxLockInfo.DevOffline = DEV_IS_ONLINE;   //在线状态初始化
	Rs485WxLockInfo.DevOfflineLast = DEV_IS_ONLINE;   //在线状态初始化
	
	switch(BUS_Public.Protocol)
	{
		case	 ENUM_RS485_DEV_PRO_01: if(NULL!=RS485_DEV_PRO_FUN_01) RS485_DEV_PRO_FUN_01(&BUS_Public, &Rs485WxLockInfo);break; //        
		case	 ENUM_RS485_DEV_PRO_02: if(NULL!=RS485_DEV_PRO_FUN_02) RS485_DEV_PRO_FUN_02(&BUS_Public, &Rs485WxLockInfo);break; //          
		case	 ENUM_RS485_DEV_PRO_03: if(NULL!=RS485_DEV_PRO_FUN_03) RS485_DEV_PRO_FUN_03(&BUS_Public, &Rs485WxLockInfo);break;                                 //3
		case	 ENUM_RS485_DEV_PRO_04: 
			if(NULL!=RS485_DEV_PRO_FUN_04) {
				//杨格锁驱动 - 特殊处理
				Rs485WxLockInfo.YG_IdVldPeriod = 300000;       //默认身份有效期,5min
				if(data[23] == 0x01){                           //秒
					Rs485WxLockInfo.YG_IdVldPeriod = (data[24]*1000);
				}else if(data[23] == 0x02){                     //分
					Rs485WxLockInfo.YG_IdVldPeriod = (data[24]*60*1000);
				}
				
				RS485_DEV_PRO_FUN_04(&BUS_Public, &Rs485WxLockInfo);
			}
			break;
        case	 ENUM_RS485_DEV_PRO_05: if(NULL!=RS485_DEV_PRO_FUN_05) RS485_DEV_PRO_FUN_05(&BUS_Public, &Rs485WxLockInfo);break;
	}
	DevActionGlobal.Lock485Addr = BUS_Public.addr; 

	switch(dev_info->port)
	{
		case Active_Port:   //主动端口
			BUS_Public.port = Active_Port;		//设备发送端口
			Add_ACT_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485WxLockInfo,sizeof(RS485_WxLock_INFO));
			Act485_Info.device_num += 1;
			break;  
		case Polling_Port:   //轮询端口
			BUS_Public.port = Polling_Port;		//设备发送端口
			Add_POLL_Device_To_List2(&BUS_Public,(uint8_t *)&Rs485WxLockInfo,sizeof(RS485_WxLock_INFO));   //将填充后的数据添加到链表
			Poll485_Info.device_num += 1;	
			break;
		case Bus_port:    //总线端口
			break;
	}

}






/**
  * @brief					   微信锁控制接口函数        
  * @param  
  *    Rs485WxLockInfo 微信锁数据结构体     
	*    Addr  		       无
	*    OnOff           无
  * @retval 无
	* @brief  					 指定微信锁打开
  * @attention  			 微信锁只控制开，不控制关
  */
void RS485_WxLock_IndiCtrl(uint32_t CfgDevAddIn, uint16_t DevInputAddr, uint32_t devaddr, uint16_t Addr, uint16_t OnOff)
{
	RS485_WxLock_INFO Rs485WxLockInfo;
	uint8_t temp1 = 0;  //crc_val = 0,
//	uint16_t DataLen;
	Device_Public_Information_G BUS_Public;
	
	if(NULL == devaddr)
	{
		return ;
	}
	
	SRAM_DMA_Read_Buff((uint8_t *)&Rs485WxLockInfo,sizeof(RS485_WxLock_INFO),devaddr+Dev_Privately);
	SRAM_Read_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), devaddr);  
	switch(OnOff&0x00ff)
	{
		case 0x01:  //开锁
		case 0x02:  //关锁

			Dbg_Println(DBG_BIT_LOGIC_STATUS_bit,"锁控制和锁请求标志置位");		//
			Rs485WxLockInfo.WeixinAskLockFlag = 0x01;   //请求开锁标志置位
			Rs485WxLockInfo.WeixinCtrlFlag = 0x01; 
			Rs485WxLockInfo.WeixinCtrlSendCnt = WxLockCtrlSendMax;
			Rs485WxLockInfo.WeixinCtrlState = OnOff&0x00ff;
            Rs485WxLockInfo.YG_SendCnt = 0x00;
			temp1 = 0x01;
		
			break;
		default:
//			Rs485WxLockInfo->WeixinCtrlFlag = 0x01;  
			break;
	}
	if(0x00 != temp1)
	{
		BUS_Public.check = 0x00;
		BUS_Public.check = DoubleData_CheckSum((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G), (uint8_t *)&Rs485WxLockInfo, sizeof(RS485_WxLock_INFO));
		SRAM_DMA_Write_Buff((uint8_t *)&BUS_Public, sizeof(Device_Public_Information_G),devaddr);/*将数据保存*/
		SRAM_DMA_Write_Buff((uint8_t *)&Rs485WxLockInfo,sizeof(RS485_WxLock_INFO),devaddr+Dev_Privately);
				
	}	
	
}



