
#include "stdlib.h"
#include "dev_flash.h"
#include "elec_judge.h"
#include "CheckerExt.h"
#include "basechecker.h"
#include "elec_det.h"
#include "elec_task_slot.h"




// 扩展的检测任务，这个文件下的任务是所有模块通用的








/*rc{ 
计算异常
par0:忽略的异常代码1
par1:忽略的异常代码2
par2~par9:同上
return:无 
exe:如果计算的异常代码为不被忽略的异常，则此任务失败
}*/
static int calc_contain(uint16_t *arr,int arr_len,uint16_t item);
void CheckerExt_CalcErr(void)
{
  const scheme_def *sch=check_scheme();
  elec_judge_def *e=0;
  uint8_t marerr=0,suberr=0;
  if(sch->plan_id==0xffffffff){
    // 判定任务不存在，返回失败
    marerr=6;
    goto end;
  }
  e=malloc(sizeof(elec_judge_def));
  elec_judge(e,sch->task_num,checker_runcfg.Task_Result,
    checker_runcfg.Task_Excute,
    (uint8_t *)checker_runcfg.Test_Rtv,&marerr,&suberr);
  free(e);
  
  end:
  if((marerr!=0)&&(calc_contain(checker_runcfg.params,checker_runcfg.param_count,marerr)==0)){
    Checker_MaskResult(1,checker_runcfg.task_info.runindex);
  }else{
    Checker_MaskResult(0,checker_runcfg.task_info.runindex);
  }
}
static int calc_contain(uint16_t *arr,int arr_len,uint16_t item)
{
  for(int i=0;i<arr_len;i++){
    if(arr[i]==item)
      return 1;
  }
  return 0;
}



/*rc{ 
重新执行已执行的任务，
任务执行结果会覆盖之前执行的那次，参数也使用之前的那个参数
通过此任务调用的任务错误跳转无效
par0:要执行的任务序号
return:无
exe:如果要执行的任务序号不小于此任务则此任务失败
}*/
static int calc_skip_num(int index);
void CheckerExt_Repeat(void)
{
  int index;
  uint16_t ret=0;
  int self_index=checker_runcfg.task_info.runindex;
  if(checker_runcfg.param_count<1){
    ret=1;
    goto end;
  }
  index=checker_runcfg.params[0];
  if(index>=self_index){
    ret=2;
    goto end;
  }
  if(elec_task_env_back()){
    ret=3;
    goto end;
  }
  if(elec_check_load_task_param(index)){
    ret=4;
    goto end;
  }
  checker_runcfg.rtv_index=calc_skip_num(index);
  elec_exe_task();
  if(elec_task_env_restore()){
    ret=5;
    goto end;
  }
  
  end:
  Checker_MaskResult(ret,self_index);
}
// 计算在taskindex之前有多少个返回值
static int calc_skip_num(int index)
{
  const scheme_def *s=check_scheme();
  const scheme_task_def *t;
  int num=0;
  for(int i=0;i<index;i++)
  {
    t=&s->task[i];
    num+=t->item_num;
  }
  return num;
}



/*rc{ 
设置UID和密码到小板内存，三码绑定函数使用此数据
输入参数[0]=uid长度，[1]=pwd长度，[uid][pwd]
}*/
void CheckerExt_SetUID(void)
{
  uint8_t pwd_len=0,uid_len=0;
  uint8_t *uid_psw=(uint8_t *)checker_runcfg.params;
  uint8_t ret=0;
	uid_len = uid_psw[0];
	pwd_len = uid_psw[1];
  if(uid_len==0||pwd_len==0){
    ret=1;
  }
  checker_runcfg.uid_len=uid_len;
  checker_runcfg.pwd_len=pwd_len;
  memcpy(checker_runcfg.writeuid,uid_psw+2,uid_len);
  memcpy(checker_runcfg.writepwd,uid_psw+2+uid_len,pwd_len);
  Checker_MaskResult(ret,checker_runcfg.task_info.runindex);
}


/*rc{ 
执行动态插入的任务,
找到此插槽的所有动态任务并依次执行,如未找到则直接返回
par0:要执行的任务插槽
return:无
exe:动态插入的任务执行失败则此任务失败
}*/
void CheckerExt_Slot(void)
{
  int index;
  uint16_t ret=0;
  uint16_t exe_ret=0;
  int self_index=checker_runcfg.task_info.runindex;
  task_def *t=0;
  void *task_slot=0;
  CheckerTask fun=0;
  if(checker_runcfg.param_count<1){
    ret=1;
    goto end;
  }
  index=checker_runcfg.params[0];
  task_slot=task_slot_init();
  if(task_slot==0){
    goto end;
  }
  if(elec_task_env_back()){
    ret=2;
    goto end;
  }
  while(t=task_slot_next(task_slot,(uint8_t)index),t){
    memset(&checker_runcfg.task_info,0,sizeof(CheckerTask_Info_st));
    memset(checker_runcfg.params,0,20);
    checker_runcfg.param_count = 0;//参数个数
    checker_runcfg.rtv_count = 0;//返回值个数
    checker_runcfg.excue_rtv = 0;
    checker_runcfg.task_info.retry_time = 0;
    
    checker_runcfg.task_info.runindex=self_index;
    checker_runcfg.param_count = t->par_count;
    checker_runcfg.rtv_count = t->ret_count;
    memcpy(checker_runcfg.params,t->params,checker_runcfg.param_count*2);
    fun=elec_get_task_fun(t->task_id);
    checker_runcfg.excue_rtv=1;
    if(fun){
      fun();
      checker_runcfg.rtv_index-=checker_runcfg.rtv_count;
      t->exe_flag=1;
    }
    exe_ret|=checker_runcfg.excue_rtv;
    memcpy(t->rets,&checker_runcfg.Test_Rtv[checker_runcfg.rtv_index],checker_runcfg.rtv_count*2);
    memset(&checker_runcfg.Test_Rtv[checker_runcfg.rtv_index],0,checker_runcfg.rtv_count*2);
    if(checker_runcfg.excue_rtv){
      task_slot_add_err(task_slot,t->errcode);
    }
  }
  if(elec_task_env_restore()){
    ret=3;
    goto end;
  }
  if(exe_ret){
    ret=4;
  }
  end:
  Checker_MaskResult(ret,self_index);
}



/*rc{ 

写电阻校准值
par0:电阻校准值
ret:无
}*/
void CheckerExt_SetCbv(void)
{
  int cbv=checker_runcfg.params[0];
  int self_index=checker_runcfg.task_info.runindex;
  elec_write_resistor_cbv(cbv);
  Checker_MaskResult(0,self_index);
}





CheckerTask exttaskArray[CHECKER_EXTID_COUNT]={
  CheckerExt_CalcErr,
  CheckerExt_Repeat,
  CheckerExt_SetUID,
  CheckerExt_Slot,
  CheckerExt_SetCbv,
};

