#include "config_info.h"
#include "getcfg.h"
#include "onchip_flash.h"
#include "bsp_ser.h"
#include "check.h"
#include "w25q128.h"
#include "encryption_chip.h"
#include "ds3231.h"
#include "udp.h"

u_int8_t g_device_local_ip[21];
u_int8_t g_device_mac[21];
u_int8_t g_device_netmask[21];
u_int8_t g_device_gateway[21];

u_int8_t g_device_term_ip[21];
u_int8_t g_device_a9_ip[21];
u_int8_t g_device_server_ip[21];
u_int8_t g_device_web_ip[21];

int ipStrValid( const char * str_ip,u_int8_t  *rvalue);
/******************************************************************************
** 文件名称：config.c
** 功    能：包含所有配置相关的函数
** 修改日志：
******************************************************************************/

static u_int8_t config_buff[1500];
/******************************************************************************
** 文件名称：read_config_file
** 功    能：从片内flash中读ini文件
** 修改日志：
******************************************************************************/
static BOOL read_config_file(void)
{           
 if (!app_crc_OK(HY_PKG_TYPE_CFG_FILE)){//校验失败
      memset(system_info.cmd_id, 0x30, sizeof(system_info.cmd_id));
      term_printf("\n读取配置文件失败\n\r");  
      return FALSE;
  }
  if (!pack_head_verify(HY_PKG_TYPE_CFG_FILE)){//检查包头数据有效性
      term_printf("\n读取配置文件失败\n\r");  
      return FALSE;
   }   
 
  return TRUE;
}

/******************************************************************************
** 文件名称：get_system_config_from_file(void)
** 功    能：得到配置信息
** 修改日志：
******************************************************************************/  
BOOL  get_system_config_from_file(void)
{     
   unsigned long ret =1;
  
   if (!read_config_file())
        return FALSE;
   
/******************************************************************************
  [rf]主机类型
*******************************************************************************/ 
   //RF
    ret = GetConfigFromBuf("rf",
		          "host_type",
		          "0",
	                  (char *)&sys_rf.host_type,
		           sizeof(sys_rf.host_type),
		          (char *)config_buff
		    );
   if (ret != 0){
       sys_rf.host_type -='0';
       term_printf("\n获取RF配置信息失败\n\r");
      // return FALSE; 
   }else{
       term_printf("\n主机类型:     ");
       sys_rf.host_type -='0';
       if (sys_rf.host_type == RF_HOST)
           term_printf("RF(一体机)\n\r");           
       else if(sys_rf.host_type == RF_RELAY)
           term_printf("RF(中继主机)\n\r");
       else if(sys_rf.host_type == RF_UNDEFINE)
           term_printf("普通主机(无RF)\n\r"); 
   } 

   //rf_sync_num
   if(sys_rf.host_type != RF_UNDEFINE){
       ret = GetConfigFromBuf("rf",
                              "sync_num",
                              "HY0000",
                              (char *)sys_rf.sync_num,
                              sizeof(sys_rf.sync_num),
                              (char *)config_buff
                        );
       if (ret != 0)
           term_printf("\n获取RF同步号码失败\n\r");
       else
           term_printf("RF同步号码:   %s\n\r",sys_rf.sync_num);
   }     
   
/******************************************************************************
  [host_mk60_cfg]
*******************************************************************************/
   //硬件版本号   
   ret = GetConfigFromBuf("host_mk60_cfg",
		          "hardwarever",
		          "00000000000000",
	                  (char *)system_info.hardware_version,
		          sizeof(system_info.hardware_version),
		          (char *)config_buff
		    );
   if (ret != 0){
       term_printf("\n获取硬件版本号失败\n\r");
   }else{
       term_printf("硬件版本号:   %s\n\r",system_info.hardware_version);
   }
   
   //公司出厂唯一CMDid号
   ret = GetConfigFromBuf("host_mk60_cfg",
		          "cmd_id",
		          "HY_OLMS_000000000",
	                  (char *)system_info.cmd_id,//终端id
		          sizeof(system_info.cmd_id),
		          (char *)config_buff
		    );
   if (ret != 0){
       term_printf("\n获取汇源ID失败\n\r");
   }else{
       term_printf("汇源ID:       %s\n\r",system_info.cmd_id);
   }
   
   //公司出厂唯一被监测设备id号
    ret = GetConfigFromBuf("host_mk60_cfg",
		          "component_id",
		          "SD__0000000000",
	                  (char *)system_info.component_id,
		          sizeof(system_info.component_id),
		          (char *)config_buff
		    );
   if (ret != 0){
       term_printf("\n获取汇源被监测ID失败\n\r");
   }else{
       term_printf("汇源被监测ID; %s\n\r",system_info.component_id);
   } 
   
 /******************************************************************************
  net
*******************************************************************************/    
  //[local]
  //ip
   
  ret = GetConfigFromBuf("local",
                        "ip",
                        "172.16.17.14",
                        (char *)g_device_local_ip,
                        sizeof(g_device_local_ip),
                        (char *)config_buff
                  );
 if (ret != 0){
   term_printf("获取本地ip地址失败,默认 :%s\n\r",g_device_local_ip);
   ipStrValid((const char *)g_device_local_ip,g_local_ip);
 }else{
     term_printf("local_ip; %s\n\r",g_device_local_ip);
     ipStrValid((const char *)g_device_local_ip,g_local_ip);
 }        

 //mac
  ret = GetConfigFromBuf("local",
                        "mac",
                        "00:01:00:00:00:02",
                        (char *)g_device_mac,
                        sizeof(g_device_mac),
                        (char *)config_buff
                  );
 if (ret != 0){
   term_printf("获取mac地址失败,默认 :%s\n\r",g_device_mac);
   macStrValid((const char *)g_device_mac,g_local_mac);
 }else{
    term_printf("mac; %s\n\r",g_device_mac);
    macStrValid((const char *)g_device_mac,g_local_mac);
 }        
 
 //netmask
  ret = GetConfigFromBuf("local",
                        "netmask",
                        "255.255.252.0",
                        (char *)g_device_netmask,
                        sizeof(g_device_netmask),
                        (char *)config_buff
                  );
 if (ret != 0){
   term_printf("获取子网掩码失败，默认netmask: %s\n\r",g_device_netmask);
   ipStrValid((const char *)g_device_netmask,g_netmask);
 }else{
     term_printf("netmask; %s\n\r",g_device_netmask);
     ipStrValid((const char *)g_device_netmask,g_netmask);
 }
  
   //gateway
  ret = GetConfigFromBuf("local",
                        "gateway",
                        "172.16.16.54",
                        (char *)g_device_gateway,
                        sizeof(g_device_gateway),
                        (char *)config_buff
                  );
 if (ret != 0){
   term_printf("获取网关失败，默认gateway: %s\n\r",g_device_gateway);
   ipStrValid((const char *)g_device_gateway,g_gateway);
 }else{
     term_printf("gateway; %s\n\r",g_device_gateway);
     ipStrValid((const char *)g_device_gateway,g_gateway);
 } 
  
 //[server]   
 //[term]
  ret = GetConfigFromBuf("server",
                        "term_ip",
                        "172.16.17.11",
                        (char *)g_device_term_ip,
                        sizeof(g_device_term_ip),
                        (char *)config_buff
                  );
 if (ret != 0){
   term_printf("获取终端ip地址失败,默认 :%s\n\r",g_device_term_ip);
   ipStrValid((const char *)g_device_term_ip,net_devices[0].ip);
 }else{
     term_printf("term_ip; %s\n\r",g_device_term_ip);
     //转换获取的地址
     ipStrValid((const char *)g_device_term_ip,net_devices[0].ip);
 }    

 //a9 ip
  ret = GetConfigFromBuf("server",
                        "a9_ip",
                        "172.16.16.54",
                        (char *)g_device_a9_ip,
                        sizeof(g_device_a9_ip),
                        (char *)config_buff
                  );
 if (ret != 0){
   term_printf("获取服务器a9 ip地址失败,默认 :%s\n\r",g_device_a9_ip);
   ipStrValid((const char *)g_device_a9_ip,net_devices[1].ip);
 }else{
     term_printf("a9_ip; %s\n\r",g_device_a9_ip);
     ipStrValid((const char *)g_device_a9_ip,net_devices[1].ip);
 }
 
 //web ip
  ret = GetConfigFromBuf("server",
                        "web_ip",
                        "118.123.114.8",
                        (char *)g_device_web_ip,
                        sizeof(g_device_web_ip),
                        (char *)config_buff
                  );
 if (ret != 0){
   term_printf("获取web ip地址失败,默认 :%s\n\r",g_device_web_ip);
   ipStrValid((const char *)g_device_web_ip,net_devices[4].ip);
 }else{
     term_printf("web_ip; %s\n\r",g_device_web_ip);
     ipStrValid((const char *)g_device_web_ip,net_devices[4].ip);
 }  
   
 /******************************************************************************
  [cert]
*******************************************************************************/     
    //证书批次号
   //batch_num
   ret = GetConfigFromBuf("cert",
		          "batch_num",
		          "000",
	                  (char *)system_info.batch_num,
		          sizeof(system_info.batch_num),
		          (char *)config_buff
		    );
   if (ret != 0){
       term_printf("\n获取证书批次号失败\n\r"); 
   }else{
       term_printf("\n证书批次号: ");
       term_printf("%s\n\r",system_info.batch_num);  
   }
   
   //同一批次证书序列号
   ret = GetConfigFromBuf("cert",
		          "serial_num",
		          "0000",
	                  (char *)system_info.cert_num,
		          sizeof(system_info.cert_num),
		          (char *)config_buff
		    );
   if (ret != 0){
       term_printf("\n获取证书序列号失败\n\r"); 
   }else{
       term_printf("证书序列号: ");
       term_printf("%s\n\r",system_info.cert_num);  
   }
   
   //申请证书时候的id
   ret = GetConfigFromBuf("cert",
		          "encryption_id",
		          "ENCRYPTION_000000",
	                  (char *)system_info.encryption_id,
		          sizeof(system_info.encryption_id),
		          (char *)config_buff
		    );
   if (ret != 0){
       term_printf("\n获取申请加密证书设备ID失败\n\r");
   }else{
       term_printf("申请加密证书设备ID; %s\n\r",system_info.encryption_id);
   }   
   
/******************************************************************************
  电池
*******************************************************************************/ 
   //电池1是否配置
   ret = GetConfigFromBuf("bat",
		          "bat1_cfg",
		          "0",
	                  (char *)&sys_bat.bat1_cfg,
		           sizeof(sys_bat.bat1_cfg),
		          (char *)config_buff
		    );
   if (ret != 0){
       sys_bat.bat1_cfg -='0';
       term_printf("\n获取电池1功能配置失败\n\r");
   }else{
       sys_bat.bat1_cfg -='0';
       term_printf("\n电池1功能:     ");
       if (sys_bat.bat1_cfg)
           term_printf("开启\n\r");           
       else
           term_printf("关闭\n\r");
   }
   
   //电池2是否配置
   ret = GetConfigFromBuf("bat",
		          "bat2_cfg",
		          "0",
	                  (char *)&sys_bat.bat2_cfg,
		           sizeof(sys_bat.bat2_cfg),
		          (char *)config_buff
		    );
   if (ret != 0){
       sys_bat.bat2_cfg -='0';
       term_printf("\n获取电池2功能配置失败\n\r");
   }else{
       sys_bat.bat2_cfg -='0'; 
       term_printf("电池2功能:     ");
       if (sys_bat.bat2_cfg)
           term_printf("开启\n\r");           
       else
           term_printf("关闭\n\r");
   }
   
      //电池3是否配置
   ret = GetConfigFromBuf("bat",
		          "bat3_cfg",
		          "0",
	                  (char *)&sys_bat.bat3_cfg,
		           sizeof(sys_bat.bat3_cfg),
		          (char *)config_buff
		    );
   if (ret != 0){
       sys_bat.bat3_cfg -='0';
       term_printf("\n获取电池3功能配置失败\n\r");
   }else{
       sys_bat.bat3_cfg -='0';
       term_printf("电池3功能:     ");
       if (sys_bat.bat3_cfg)
           term_printf("开启\n\r");           
       else
           term_printf("关闭\n\r");
   }
   
  //电池4是否配置
   ret = GetConfigFromBuf("bat",
		          "bat4_cfg",
		          "0",
	                  (char *)&sys_bat.bat4_cfg,
		           sizeof(sys_bat.bat4_cfg),
		          (char *)config_buff
		    );
   if (ret != 0){
       sys_bat.bat4_cfg -='0';
       term_printf("\n获取电池4功能配置失败\n\r");
   }else{
       sys_bat.bat4_cfg -='0';
       term_printf("电池4功能:     ");
       if (sys_bat.bat4_cfg)
           term_printf("开启\n\r");           
       else
           term_printf("关闭\n\r");
   }
 
      //电池5是否配置
   ret = GetConfigFromBuf("bat",
		          "bat5_cfg",
		          "0",
	                  (char *)&sys_bat.bat5_cfg,
		           sizeof(sys_bat.bat5_cfg),
		          (char *)config_buff
		    );
   if (ret != 0){
       sys_bat.bat5_cfg -='0';
       term_printf("\n获取电池5功能配置失败\n\r");
   }else{
       sys_bat.bat5_cfg -='0';
       term_printf("电池5功能:     ");
       if (sys_bat.bat5_cfg)
           term_printf("开启\n\r");           
       else
           term_printf("关闭\n\r");
   }
         
 
  
/******************************************************************************

*******************************************************************************/      
   //读出FLASH存储的设备总运行时间
   Flash_Read((u_int8_t *)&device_work_information,FLASH_DEVICE_WORK_INFO_ADDR_BEGIN,sizeof(device_work_information));
   if((device_work_information.head == DEVICE_SAVE_HEAD)&&(device_work_information.end == DEVICE_SAVE_END)){
       g_device_last_save_total_working_time = device_work_information.total_work_time;
       g_send_flow = device_work_information.total_send_flow; 
       g_receive_flow = device_work_information.total_receive_flow; 
       g_hy_send_flow = device_work_information.hy_total_send_flow; 
       g_hy_receive_flow = device_work_information.hy_total_receive_flow;    
   }
   BSP_OS_TimeDlyMs(10);
   term_printf("\n国网通道:当月已发送流量：%d\n\r",g_send_flow);
   term_printf("国网通道:当月已接收流量：%d\n\r",g_receive_flow);
   term_printf("汇源通道:当月已发送流量：%d\n\r",g_hy_send_flow);
   term_printf("汇源通道:当月已接收流量：%d\n\r",g_hy_receive_flow);  

   return TRUE;   
}

/******************************************************************************
** 文件名称： get_key_from_file
** 功    能：从片内flash中读公钥文件
** 修改日志：
******************************************************************************/

BOOL get_key_from_file(void)
{ 
   hy_release_file_head h_read; 
  if (!app_crc_OK(HY_PKG_TYPE_PUB_KEY)){//校验失败
      term_printf("\n读取安全接入平台公钥文件失败\n\r");  
      return FALSE;
  }
  if (!pack_head_verify(HY_PKG_TYPE_CERT)){//检查包头数据有效性
      term_printf("\n读取安全接入平台公钥文件失败\n\r");  
      return FALSE;
  }
  Flash_Read((u_int8_t *)&h_read, KEY_HEAD_BEGIN, sizeof(h_read)); 
  memcpy(system_info.key,&config_buff[4],(h_read.data_len)-4);//copy公钥//150813南瑞测试没有前4个无效字节
  term_printf("\n获取安全接入平台公钥成功\n\r");//去掉前4个字节

  if (encryption_chip_sm2_import_public_key(1,system_info.key)){
      term_printf("向加密芯片导入安全接入平台公钥成功");
  }else
      term_printf("\n向加密芯片导入安全接入平台公钥失败");
  
  return TRUE;
}

/******************************************************************************
** 文件名称： get_cert1_from_file
** 功    能：从片外flash中读公钥文件
** 修改日志：
******************************************************************************/

BOOL get_cert1_from_file(void)
{           
  hy_release_file_head h_read; 
  
  if (!app_crc_OK(HY_PKG_TYPE_CERT)){//校验失败
      term_printf("\n读取安全证书文件失败\n\r");  
      return FALSE;
  }
  
  if (!pack_head_verify(HY_PKG_TYPE_CERT)){//检查包头数据有效性
      term_printf("\n读取安全证书文件失败\n\r");  
      return FALSE;
   } 
  
  Flash_Read((u_int8_t *)&h_read, CERT_HEAD_BEGIN, sizeof(h_read)); 
  memcpy(system_info.cert1,config_buff,h_read.data_len);//copy安全证书
  system_info.cert1_len = h_read.data_len;//证书长度
  if (system_info.cert1_len < 200){
       term_printf("\n读取安全证书长度失败\n\r");
       return FALSE;
  }     
  term_printf("\n获取安全证书成功\n\r");
  return TRUE;
}

/******************************************************************************
** 函数名称:check_sum
** 功    能：
** 修改日志：
******************************************************************************/
static u_int8_t check_sum(u_int8_t *p, int len)
{
        u_int8_t ret = 0;
        int i = 0;

        for(; i<len; i++)
        {  
                ret += p[i];
        }        
        return (~ret)+1;
}

/******************************************************************************
** 函数名称:upgrade_pkg_head_checksum_OK
** 功    能：检查升级包头的checksum
** 修改日志：
******************************************************************************/
u_int8_t upgrade_pkg_head_checksum_OK(hy_release_file_head *pkg_head)
{
  return check_sum((u_int8_t *)pkg_head, (u_int8_t *)(&pkg_head->head_checksum) - (u_int8_t *)pkg_head)
    == pkg_head->head_checksum;
}

/******************************************************************************
** 函数名称：ext_flash_erase
** 功    能：擦除片外rom中的存储空间
** 修改日志：
******************************************************************************/
BOOL ext_flash_erase(hy_release_file_head *pkg_head)
{
  u_int32_t total_len = pkg_head->data_len;

 if(pkg_head->file_type == HY_PKG_TYPE_PUB_KEY){
    if((pkg_head->addr + total_len) > KEY_ADDR_END)
       return FALSE;
       Flash_Erase_Sector(EXT_FLASH_BLOCK_NUM,KEY_HEAD_SECTOR_BEGIN);
       Flash_Erase_Sector(EXT_FLASH_BLOCK_NUM,KEY_SECTOR_BEGIN);       
  }else if(pkg_head->file_type == HY_PKG_TYPE_CERT){
    if((pkg_head->addr + total_len) > CERT_ADDR_END)
       return FALSE;
    Flash_Erase_Sector(EXT_FLASH_BLOCK_NUM,CERT_HEAD_SECTOR_BEGIN);
    Flash_Erase_Sector(EXT_FLASH_BLOCK_NUM,CERT_SECTOR_BEGIN);      
  }else if(pkg_head->file_type == HY_PKG_TYPE_CFG_FILE){
    if((pkg_head->addr + total_len) > CFG_FILE_ADDR_END)
       return FALSE;
     Flash_Erase_Sector(EXT_FLASH_BLOCK_NUM,CFG_FILE_HEAD_SECTOR_BEGIN);
     Flash_Erase_Sector(EXT_FLASH_BLOCK_NUM,CFG_FILE_SECTOR_BEGIN);  
  }
     
  return TRUE;
}
/******************************************************************************
** 函数名称: app_crc_OK
** 功    能：校验已写入片内rom的应用程序包 通过crc16方式校验
** 修改日志：
******************************************************************************/

BOOL app_crc_OK(u_int8_t file_type)
{
  u_int16_t crc16;
  hy_release_file_head h_read;  
  u_int8_t crc16_read2[2] = {0x00}; 
  u_int32_t read_addr = 0;
  u_int32_t read_len = 0;
  
    if (file_type == HY_PKG_TYPE_CERT){
        Flash_Read((u_int8_t *)&h_read, CERT_HEAD_BEGIN, sizeof(h_read)-1);
        if(h_read.file_type != HY_PKG_TYPE_CERT)
            return FALSE;
        if (!upgrade_pkg_head_checksum_OK(&h_read))
            return FALSE;
         read_addr = CERT_ADDR_BEGIN;
     }else if (file_type == HY_PKG_TYPE_PUB_KEY){
        Flash_Read((u_int8_t *)&h_read, KEY_HEAD_BEGIN, sizeof(h_read)-1);
        if(h_read.file_type != HY_PKG_TYPE_PUB_KEY)
            return FALSE;
        if (!upgrade_pkg_head_checksum_OK(&h_read))
            return FALSE;
         read_addr = KEY_ADDR_BEGIN;
     }else if (file_type == HY_PKG_TYPE_CFG_FILE){
         Flash_Read((u_int8_t *)&h_read,CFG_FILE_HEAD_BEGIN, sizeof(h_read)-1);
         if(h_read.file_type != HY_PKG_TYPE_CFG_FILE)
            return FALSE;
         if (!upgrade_pkg_head_checksum_OK(&h_read))
            return FALSE;
          read_addr = CFG_FILE_ADDR_BEGIN; 
     }      
     CRC16_init(&crc16);
    //先算包头crc
     CRC16_update(&crc16,(u_int8_t *)&h_read, sizeof(h_read)-1);
     read_len = h_read.data_len; //包括crc16内容
     if(read_len > 1000)
       return FALSE;
     Flash_Read(config_buff, read_addr,read_len);
     Flash_Read((u_int8_t *)crc16_read2, read_addr+read_len,sizeof(u_int16_t));
     CRC16_update(&crc16,config_buff, read_len);
     
     return crc16 == *(u_int16_t *)&crc16_read2;
}

/******************************************************************************
 *函数名: write_pack_head_to_ext_flash
 *功  能：写包头到片外flash中
 *参  数：
 *返回值：
 *修  改：
******************************************************************************/
BOOL write_pack_head_to_ext_flash(hy_release_file_head *pkg_head)
{ 
  
  if(pkg_head->file_type == HY_PKG_TYPE_PUB_KEY){
      Flash_Write_MorePage((u_int8_t *)pkg_head,KEY_HEAD_BEGIN,sizeof(*pkg_head));
  }else if(pkg_head->file_type == HY_PKG_TYPE_CERT){
      Flash_Write_MorePage((u_int8_t *)pkg_head,CERT_HEAD_BEGIN,sizeof(*pkg_head)); 
  }else if(pkg_head->file_type == HY_PKG_TYPE_CFG_FILE){
      Flash_Write_MorePage((u_int8_t *)pkg_head,CFG_FILE_HEAD_BEGIN,sizeof(*pkg_head));
  }
  
  return TRUE;
}

/******************************************************************************
 *函数名: write_file_to_ext_flash
 *功  能：写文件到外部flash中
 *参  数：
 *返回值：
 *修  改：
******************************************************************************/
BOOL write_file_to_ext_flash(hy_release_file_head *pkg_head)
{;
  u_int32_t len = pkg_head->data_len + sizeof(u_int16_t); //内容+crc16
  u_int32_t write_addr = pkg_head->addr;
  Flash_Write_MorePage(pkg_head->data,write_addr,len);
  return TRUE;
}
                          
/******************************************************************************
 *函数名: pack_head_verify
 *功  能：校验包头数据的有效性
 *参  数：
 *返回值：
 *修  改：
******************************************************************************/
BOOL pack_head_verify(u_int8_t file_type)
{
  hy_release_file_head pkg_head = {0x00};
  u_int32_t read_addr;
  
   if (file_type == HY_PKG_TYPE_PUB_KEY){
       read_addr = KEY_HEAD_BEGIN;
   }else if (file_type == HY_PKG_TYPE_CERT){
       read_addr = CERT_HEAD_BEGIN;
   }else if (file_type == HY_PKG_TYPE_CFG_FILE){  
       read_addr = CFG_FILE_HEAD_BEGIN;
   } 
   
   Flash_Read((u_int8_t *)&pkg_head,read_addr, sizeof(pkg_head)-1);
  
  //数据长度限制
  if((pkg_head.data_len) > (1024*2))
    return FALSE;
 
  //起始标志检查
  if(pkg_head.flag != HY_RELEASE_FILE_FLAG)
    return FALSE;
  
  //头长度检验
  if(pkg_head.head_len != (sizeof(pkg_head)-1))
    return FALSE;
  
  //文件类型检验 boot app cert key cfg_file
  if((pkg_head.file_type != HY_PKG_TYPE_APP) && (pkg_head.file_type != HY_PKG_TYPE_BOOT_LOADER) && (pkg_head.file_type != HY_PKG_TYPE_CERT) && (pkg_head.file_type != HY_PKG_TYPE_PUB_KEY)&& (pkg_head.file_type != HY_PKG_TYPE_CFG_FILE))
    return FALSE;
  
  //文件格式版本
  if(pkg_head.file_format_ver != 1)
    return FALSE;  
  
  if(pkg_head.file_type == HY_PKG_TYPE_APP){ //App
    //烧写地址检验
    if(pkg_head.addr < APP_ADDR_BEGIN)
      return FALSE;
    //空间检验
    if((pkg_head.addr + pkg_head.data_len) > APP_ADDR_END)
      return FALSE;
  }else if(pkg_head.file_type == HY_PKG_TYPE_BOOT_LOADER){ //Bootloader
    //烧写地址检验
    if(pkg_head.addr != 0) //bootloader必须以0为起始地址
      return FALSE;
    //空间检验
    if((pkg_head.addr + pkg_head.data_len) > BOOTLOADER_ADDR_END)
      return FALSE;
  }else if(pkg_head.file_type == HY_PKG_TYPE_CERT){//CERT
     //烧写地址
    if(pkg_head.addr < CERT_ADDR_BEGIN)
      return FALSE;
    //空间检验
    if((pkg_head.addr + pkg_head.data_len) > CERT_ADDR_END)
      return FALSE;    
  }else if(pkg_head.file_type == HY_PKG_TYPE_PUB_KEY){//KEY
     //烧写地址
    if(pkg_head.addr < KEY_ADDR_BEGIN)
      return FALSE;
    //空间检验
    if((pkg_head.addr + pkg_head.data_len) > KEY_ADDR_END)
      return FALSE;   
  }else if(pkg_head.file_type == HY_PKG_TYPE_CFG_FILE){//CFG FILE
     //烧写地址
    if(pkg_head.addr < CFG_FILE_ADDR_BEGIN)
      return FALSE;
    //空间检验
    if((pkg_head.addr + pkg_head.data_len) > CFG_FILE_ADDR_END)
      return FALSE;   
  }  
  return TRUE;
}

//擦除片外flash缓存空间
void erase_ext_flash(u_int8_t block_begin,u_int32_t total_len)
{
  int i = 0;
  int block_count = total_len / Flash_BLOCKBYTE_LENGTH;
  
  if(total_len % Flash_BLOCKBYTE_LENGTH)
    block_count++;
  
  for(i = 0; i<block_count; i++){
    Flash_Erase_Block(block_begin + i);
    BSP_OS_TimeDlyMs(10);
  }
}

/******************************************************************************
** 函数名称：
** 功    能：将字符转成整数  如“192.168.8.1”转成192 168 8 1存在2个数组中
** 入口参数：
** 出口参数：
*******************************************************************************/
int ipStrValid( const char * str_ip,u_int8_t  *rvalue)
{
	char	p[20];
	int	n,i,dotnumber,j;
	int	num_len=0;
	
	char	k[4];
	
        memset(p,0,sizeof(p));
	if(str_ip==NULL)
		return 0;
	n=strlen(str_ip);
	if(n==0)
		return 0;
	j=0;
	dotnumber=0;
	for(i=0;i<n;i++)
	{
		if(str_ip[i]=='.')
		{
			p[j]=0;
			num_len = strlen(p);
			if( num_len  == 0 )
				return 0;
			k[dotnumber] = atoi(p);
			//if(k[dotnumber]>252)
			//	return 0;
			dotnumber++;
			if(dotnumber>3)
				return 0;
			j=0;
			continue;
		}
		else if( (str_ip[i]<='9') && (str_ip[i]>='0') )
		{
			p[j++]=str_ip[i];
		}
		else
		{
			return 0;
		}
	}
	p[j]=0;
	k[3]=atoi(p);        
	if(dotnumber!=3)
		return 0;
	if(k[3]>=255)//默认不能等于255 广播地址
		return 0;
        memcpy(rvalue,k,4);//拷贝到目标数组中
	return 1;	
};

