/******************************************************************************
版权所有：	
文件名称：	auth.c
文件版本：	01.01
创建作者：	sunxi
创建日期：	2016-04-21
功能说明：	装置授权管理
其它说明：
修改记录：
*/
/*------------------------------- 头文件 --------------------------------------
*/
#include "head.h"
#include "base64.h"
 
/*------------------------------- 宏定义 --------------------------------------
*/
#define AUTH_BUF_LEN		64


/*------------------------------ 类型结构 -------------------------------------
*/


/*------------------------------ 全局变量 -------------------------------------
*/
u8 g_auth_id[AUTH_ID_LEN];

/*------------------------------ 函数声明 -------------------------------------
*/
int read_unique_id(unsigned char *id);


/*------------------------------ 外部函数 -------------------------------------
外部函数供其它实体文件引用，必须仔细检查传入参数的合法性.
*/
int auth_verify(u8 * data,int len)
{
	return 0;	
}

int auth_get_status(void)
{
	return 0;
}
int auth_master_index(void)
{
	return 0;
}
int auth_encrypt(u8 * id,u8 * id0,u8 * data,int len)
{
	return 0;	
}

int auth_get_encrypt_id(u8 * id,int len)
{
#define ID_ENCRPT_LEN	32
	return ID_ENCRPT_LEN;
}
int auth_init(void)
{
	int ret=0;
#ifndef CPU_FUXI
	printk("HZ = %d\n", HZ);
#endif
	ret = read_unique_id(g_auth_id);
	if(ret != 0)
	{
		return -1;
	}

	if(auth_master_index() >= 0)
	{
		return 0;
	}

	ret = auth_check();
	if(ret != 0)
	{
		u8 buf[AUTH_LICENSE_LEN];
		char sz[AUTH_BUF_LEN];
		
		auth_get_encrypt_id(buf,AUTH_LICENSE_LEN);
		encode_base64(sz,buf,AUTH_LICENSE_LEN);
		//print_mem("id:",buf,32);
		rt_printf("授权标识码:%s\r\n",sz);
	}
	
	return ret;
}


int auth_exit(void)
{
	return 0;
}

//int auth_get_encrypt_id(u8 *id,

#define BASE64_LENGTH(len)  (4 * ((len + 2) / 3))
int auth_save(u8 *buf,u32 len)
{
	char sz[AUTH_BUF_LEN];
	int ret;

	ret = auth_verify(buf,AUTH_LICENSE_LEN);
	if(ret != 0)
	{
		rt_err_set(ERR_CODE_AUTH,0);
		rt_printf("auth_verify:ret=%d.\r\n",ret);
		return -1;
	}
	else
	{
		rt_err_clr(ERR_CODE_AUTH,0);
	}
	
	
	if(BASE64_LENGTH(len) >= AUTH_BUF_LEN)
	{
		return -1;
	}
	print_mem("auth_save:",buf,len);
	encode_base64(sz,buf,len);

	env_setenv("auth",sz);
	
	return 0;
}

int auth_check(void)
{
	char * sz;
	char  buf[64],*p;
	int ret;

	sz = env_get_info(ENV_AUTH);
	if(sz == NULL)
	{
		rt_err_set(ERR_CODE_AUTH,0);
		rt_printf("没有授权信息!\r\n");
		return -11;
	}

	p = buf;
	decode_base64(&p,sz);

	//print_mem("auth_check:",buf,32);
	ret = auth_verify(buf,AUTH_LICENSE_LEN);
	if(ret != 0)
	{
		rt_err_set(ERR_CODE_AUTH,0);
		rt_printf("auth_verify:ret=%d.\r\n",ret);
	}
	else
	{
		rt_printf("装置通过授权检查!\r\n");
	}
	
	return ret;
}

int auth_license(u8 * id ,struct rtc_time_t *p_tm,u8* license)
{
	char log[128];
	u8 id0[32];
	int len,i,ret;
	struct rtc_time_t tm;

	// 如果不是授权机，返回
	if(auth_master_index() < 0)
	{
		return -1;
	}

	// 如果授权文件已满，停止授权
	if(log_file_is_overrun(LOG_AUTH))
	{
		return -2;
	}

	// 授权
	//print_mem("     id:",id,32);
	ret = auth_encrypt(id,id0,license,32);
	if(ret < 0)
	{
		rt_printf("auth_encrypt error:ret=%d.\r\n",ret);
		print_mem("     id:",id,32);
		print_mem("    id0:",id0,32);
		print_mem("license:",license,32);
		return ret;
	}
	//print_mem("license:",license,32);

	// 如果授权成功，记录授权数据
	memcpy(&tm,p_tm,sizeof(tm));
	sprintf(log,"20%02hu-%02hu-%02hu %02hu:%02hu:%02hu.%06u 授权成功[%02d]:",tm.year,tm.month,tm.day,tm.hour,tm.min,tm.ms/1000,tm.ms%1000*1000,ret);
	len = strlen(log);

	for(i=0;i<8;i++)
	{
		sprintf(log+len+i*3,"%02x-",id0[i]);
		
	}
	len = strlen(log);
	log[len-1] = 0;

	log_str(LOG_AUTH,log);
	
	return 0;
}

int auth_test(void)
{
	u8 id[32],id0[32],license[32];
	int ret;
	
	auth_get_encrypt_id(id,32);
	print_mem("     id:",id,24);
	ret = auth_encrypt(id,id0,license,32);
	rt_printf("auth_encrypt:ret=%d.\r\n",ret);
	print_mem("     id:",id,24);
	print_mem("    id0:",id0,24);
	print_mem("license:",license,32);
	ret = auth_verify(license,32);
	rt_printf("auth_verify:ret=%d.\r\n",ret);

	return 0;
}

extern char * gCmdArg[32];
extern int	gCmdArgCount;

int auth_info_printf(void)
{
	int i,ret;
	u8  id[64],license[64];
	char *p;
	char sz[64];
	
	struct timespec 	ts;
	struct rtc_time_t	rt;	

	if(gCmdArgCount == 2)
	{
		p = (char *)id;
		//rt_printf("sz=%s\r\n",gCmdArg[1]);
		decode_base64(&p,gCmdArg[1]);
		clk_time_get(&ts);
		timespec_to_rtc(ts, &rt, 1);
		ret = auth_license(id,&rt,license);
		if(ret == 0)
		{
			encode_base64(sz,license,AUTH_LICENSE_LEN);	
			rt_printf("授权成功:auth=%s\r\n",sz);
		}
		else
		{
			rt_printf("授权失败:ret=%d\r\n",ret);
		}
	}
	else
	{

	rt_printf("  授权状态:%d.\r\n",auth_get_status());
	rt_printf("授权标识码:");
	for(i=0;i<8;i++)
	{
		rt_printf("%02x",g_auth_id[i]);
		if(i<7)
		{
			rt_printf("-");
		}
	}

	rt_printf("\r\n授权机索引:%d.\r\n",auth_master_index());
	} 

//	auth_test();
	

	return 0;
}

/*------------------------------ 内部函数 -------------------------------------
内部函数以下划线‘_’开头，不需要检查参数的合法性.
*/


/*------------------------------ 测试函数 -------------------------------------
一个实体文件必须带一个本模块的测试函数来进行单元测试，如果的确不方便在本模块中
进行单元测试，必须在此注明实际的测试位置（例如在哪个实体文件中使用哪个测试函数）.
*/


/*------------------------------ 文件结束 -------------------------------------
*/
