557 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			557 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "myjson.h"
 | ||
| #include "board.h"
 | ||
| #include "debug.h"
 | ||
| #include "mystdlib.h"
 | ||
| #include "bytearray.h"
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| // json字符串转化为json,返回临时指针
 | ||
| cJSON *json_parse(const char *jstr)
 | ||
| {
 | ||
|   cJSON *json=cJSON_Parse(jstr);
 | ||
|   if(json){
 | ||
|     return tappend(json,cJSON_Delete);
 | ||
|   }
 | ||
|   return json;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| /*r{ json 转列表 }c*/
 | ||
| list_def *jarray_to_list(cJSON *jarray,obj_def *obj)
 | ||
| {
 | ||
|   param_check(obj);
 | ||
|   param_check(obj->to_obj_fun);
 | ||
|   param_check(obj->obj_size);
 | ||
|   param_check(jarray);
 | ||
|   list_def *l=list_creat(obj->obj_size,obj->sub,obj->del,0);
 | ||
|   void *o;
 | ||
|   int array_size;
 | ||
|   if(jarray->type!=cJSON_Array){
 | ||
|     DBG_WARN("json:%s not a array obj.",jarray->string?jarray->string:"null");
 | ||
|     goto err;
 | ||
|   }
 | ||
|   array_size=cJSON_GetArraySize(jarray);
 | ||
|   for(int i=0;i<array_size;i++)
 | ||
|   {
 | ||
|     o=obj->to_obj_fun(cJSON_GetArrayItem(jarray,i));
 | ||
|     if(o==0)
 | ||
|     {
 | ||
|       DBG_WARN("json:%s conversion failed.",jarray->string?jarray->string:"null");
 | ||
|       goto err;
 | ||
|     }
 | ||
|     list_append(l,o);
 | ||
|     if(obj->del_fun) obj->del_fun(o);
 | ||
|   }
 | ||
|   err:
 | ||
|   return l;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| /*r{ json转整形 }c*/
 | ||
| static void *json_to_int(cJSON *j)
 | ||
| {
 | ||
|   if(j->type==cJSON_Number)
 | ||
|   {
 | ||
|     int *ret=malloc(sizeof(int));
 | ||
|     param_check(ret);
 | ||
|     *ret=j->valueint;
 | ||
|     return ret;
 | ||
|   }
 | ||
|   return 0;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| static obj_def g_obj_int={
 | ||
|   .obj_size=sizeof(int),
 | ||
|   .to_obj_fun=json_to_int,
 | ||
|   .del_fun=free,
 | ||
|   .sub=INT_SUB,
 | ||
|   .del=INT_DEL
 | ||
| };
 | ||
| 
 | ||
| 
 | ||
| obj_def *obj_int(void)
 | ||
| {
 | ||
|   return &g_obj_int;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| /*r{ json转字符串 }c*/
 | ||
| static void *json_to_str(cJSON *j)
 | ||
| {
 | ||
|   if(j->type==cJSON_String)
 | ||
|   {
 | ||
|     int len=strlen(j->valuestring)+1;
 | ||
|     char *ret=malloc(len);
 | ||
|     char **ret_ptr=malloc(sizeof(char *));
 | ||
|     param_check(ret);
 | ||
|     param_check(ret_ptr);
 | ||
|     memcpy(ret,j->valuestring,len+1);
 | ||
|     *ret_ptr=ret;
 | ||
|     return ret_ptr;
 | ||
|   }
 | ||
|   return 0;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| static obj_def g_obj_str={
 | ||
|   .obj_size=sizeof(char *),
 | ||
|   .to_obj_fun=json_to_str,
 | ||
|   .del_fun=free,
 | ||
|   .sub=STR_SUB,
 | ||
|   .del=STR_DEL
 | ||
| };
 | ||
| 
 | ||
| 
 | ||
| obj_def *obj_str(void)
 | ||
| {
 | ||
|   return &g_obj_str;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| static void *json_to_range(cJSON *j)
 | ||
| {
 | ||
|   sch_range *s=malloc(sizeof(sch_range));
 | ||
|   param_check(s);
 | ||
|   JSON_GET_INT(cJSON_GetObjectItem(j,"Max"),s->max);
 | ||
|   JSON_GET_INT(cJSON_GetObjectItem(j,"Min"),s->min);
 | ||
|   if(s->min>s->max){
 | ||
|     DBG_WARN("range is empty.");
 | ||
|   }
 | ||
|   return s;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| static obj_def g_obj_range={
 | ||
|   .obj_size=sizeof(sch_range),
 | ||
|   .to_obj_fun=json_to_range,
 | ||
|   .del_fun=free,
 | ||
|   .sub=0,
 | ||
|   .del=0
 | ||
| };
 | ||
| 
 | ||
| 
 | ||
| obj_def *obj_range(void)
 | ||
| {
 | ||
|   return &g_obj_range;
 | ||
| }
 | ||
| 
 | ||
| // 返回1,在范围内
 | ||
| int range_in_range(sch_range *r,int num)
 | ||
| {
 | ||
|   if(num>=r->min&&num<=r->max)
 | ||
|     return 1;
 | ||
|   else
 | ||
|     return 0;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| static void *json_to_task(cJSON *j)
 | ||
| {
 | ||
|   sch_task *task=calloc(1,sizeof(sch_range));
 | ||
|   JSON_GET_STR(cJSON_GetObjectItem(j,"TaskBrief"),task->brief);
 | ||
|   JSON_GET_INT(cJSON_GetObjectItem(j,"TaskID"),task->task_id);
 | ||
|   JSON_GET_INT(cJSON_GetObjectItem(j,"TaskIndex"),task->index);
 | ||
|   JSON_GET_INT(cJSON_GetObjectItem(j,"ErrJumpTo"),task->err_jump);
 | ||
|   JSON_GET_INT(cJSON_GetObjectItem(j,"RetryCount"),task->retry);
 | ||
|   JSON_GET_INT(cJSON_GetObjectItem(j,"ParamCount"),task->param_num);
 | ||
|   JSON_GET_INT(cJSON_GetObjectItem(j,"ReturnCount"),task->return_num);
 | ||
|   task->params_info=jarray_to_list(cJSON_GetObjectItem(j,"ParamInfo"),obj_str());
 | ||
|   task->returns_info=jarray_to_list(cJSON_GetObjectItem(j,"ReturnInfo"),obj_str());
 | ||
|   task->params=jarray_to_list(cJSON_GetObjectItem(j,"ParamVal"),obj_int());
 | ||
|   task->ranges=jarray_to_list(cJSON_GetObjectItem(j,"TestStandard"),obj_range());
 | ||
|   JSON_GET_INT(cJSON_GetObjectItem(j,"ExecuteErrCode"),task->failed_code);
 | ||
|   task->ret_failed_code=jarray_to_list(cJSON_GetObjectItem(j,"ResultErrCode"),obj_int());
 | ||
|   return task;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| static int _list_del_task(void *p)
 | ||
| {
 | ||
|   sch_task *t=p;
 | ||
|   CHECK_DO(t->brief,free);
 | ||
|   CHECK_DO(t->params_info,list_delete);
 | ||
|   CHECK_DO(t->returns_info,list_delete);
 | ||
|   CHECK_DO(t->params,list_delete);
 | ||
|   CHECK_DO(t->ranges,list_delete);
 | ||
|   CHECK_DO(t->ret_failed_code,list_delete);
 | ||
|   CHECK_DO(t->ch_errcode,list_delete);
 | ||
|   return 0;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| static obj_def g_obj_task={
 | ||
|   .obj_size=sizeof(sch_task),
 | ||
|   .to_obj_fun=json_to_task,
 | ||
|   .del_fun=free,
 | ||
|   .sub=0,
 | ||
|   .del=_list_del_task
 | ||
| };
 | ||
| 
 | ||
| 
 | ||
| obj_def *obj_task(void)
 | ||
| {
 | ||
|   return &g_obj_task;
 | ||
| }
 | ||
| 
 | ||
| // 任务转化为数组
 | ||
| array_def *task_to_array(sch_task *t)
 | ||
| {
 | ||
|   array_def *a=arr_creat();
 | ||
|   arr_append(a,(uint8_t)t->task_id);
 | ||
|   arr_append(a,(uint8_t)t->index);
 | ||
|   arr_append(a,(uint8_t)t->retry);
 | ||
|   arr_append(a,(uint8_t)t->err_jump);
 | ||
|   arr_append(a,(uint8_t)(t->param_num&0x0f)|(t->return_num<<4));
 | ||
|   for(int i=0;i<list_length(t->params);i++)
 | ||
|   {
 | ||
|     arr_append(a,(uint8_t)(list_get_int(t->params,i)&0xff));
 | ||
|     arr_append(a,(uint8_t)(list_get_int(t->params,i)>>8));
 | ||
|   }
 | ||
|   if(list_length(t->params)!=t->param_num)
 | ||
|   {
 | ||
|     DBG_WARN("name=%s param_num!=params.size().",t->brief);
 | ||
|   }
 | ||
|   if(t->return_num>list_length(t->returns_info))
 | ||
|   {
 | ||
|     DBG_WARN("name=%s return_num>returns_info.size().",t->brief);
 | ||
|   }
 | ||
|   if(list_length(t->ch_errcode)!=list_length(t->ranges))
 | ||
|   {
 | ||
|     DBG_WARN("name=%s ch_errcode.size()!=ranges.size().",t->brief);
 | ||
|   }
 | ||
|   return a;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| // ack==0成功
 | ||
| task_returns *task_check_returns(sch_task *t,int ack,array_def *data)
 | ||
| {
 | ||
|   int size=sizeof(task_returns)+sizeof(reurn_item)*t->return_num;
 | ||
|   task_returns *res=malloc(size);
 | ||
|   param_check(res);
 | ||
|   res->size=size;
 | ||
|   memset(res,0,size);
 | ||
|   if(t->ch_errcode==0) t->ch_errcode=list_creat_int();
 | ||
|   list_clear(t->ch_errcode);
 | ||
|   res->index=t->index;
 | ||
|   res->id=t->task_id;
 | ||
|   res->ack=ack;
 | ||
|   if(res->ack==0){
 | ||
|     res->exe_err=0;
 | ||
|   }else{
 | ||
|     res->exe_err=t->failed_code;
 | ||
|     list_append_int(t->ch_errcode,t->failed_code);
 | ||
|   }
 | ||
|   if(arr_length(data)/2<t->return_num){
 | ||
|     DBG_WARN("task=%s, data size too less.",t->brief);
 | ||
|   }else{
 | ||
|     for(int i=0;i<t->return_num;i++)
 | ||
|     {
 | ||
|       reurn_item *item=&res->items[i];
 | ||
|       int value=arr_get(data,i*2)|(arr_get(data,i*2+1)<<8);
 | ||
|       item->value=value;
 | ||
|       if(list_length(t->ranges)>i)
 | ||
|       {
 | ||
|         if(range_in_range(list_get(t->ranges,i),value))
 | ||
|           item->err=0;
 | ||
|         else{
 | ||
|           if(list_length(t->ret_failed_code)>i)
 | ||
|           {
 | ||
|             item->err=list_get_int(t->ret_failed_code,i);
 | ||
|             list_append_int(t->ch_errcode,item->err);
 | ||
|           }
 | ||
|         }
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
|   return res;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| static void *json_to_errcode(cJSON *j)
 | ||
| {
 | ||
|   sch_errcode *e=calloc(1,sizeof(sch_errcode));
 | ||
|   param_check(e);
 | ||
|   JSON_GET_INT(cJSON_GetObjectItem(j,"MajorErrCode"),e->err);
 | ||
|   JSON_GET_STR(cJSON_GetObjectItem(j,"Info"),e->info);
 | ||
|   e->suberr=jarray_to_list(cJSON_GetObjectItem(j,"SubErrCode"),obj_int());
 | ||
|   return e;
 | ||
| }
 | ||
| 
 | ||
| static int _list_del_errcode(void *p)
 | ||
| {
 | ||
|   sch_errcode *e=p;
 | ||
|   CHECK_DO(e->info,free);
 | ||
|   CHECK_DO(e->suberr,list_delete);
 | ||
|   return 0;
 | ||
| }
 | ||
| 
 | ||
| static obj_def g_obj_errcode={
 | ||
|   .obj_size=sizeof(sch_errcode),
 | ||
|   .to_obj_fun=json_to_errcode,
 | ||
|   .del_fun=free,
 | ||
|   .sub=0,
 | ||
|   .del=_list_del_errcode
 | ||
| };
 | ||
| 
 | ||
| 
 | ||
| obj_def *obj_errcode(void)
 | ||
| {
 | ||
|   return &g_obj_errcode;
 | ||
| }
 | ||
| 
 | ||
| // 返回1在范围内
 | ||
| int errcode_in_range(sch_errcode *e,int subcode)
 | ||
| {
 | ||
|   param_check(e);
 | ||
|   for(int i=0;i<list_length(e->suberr);i++)
 | ||
|   {
 | ||
|     if(subcode==list_get_int(e->suberr,i))
 | ||
|       return 1;
 | ||
|   }
 | ||
|   return 0;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| static void *_json_to_scheme(cJSON *j)
 | ||
| {
 | ||
|   scheme_def *s=calloc(1,sizeof(scheme_def));
 | ||
|   param_check(s);
 | ||
|   JSON_GET_INT(cJSON_GetObjectItem(j,"PlanID"),s->plan_id);
 | ||
|   JSON_GET_STR(cJSON_GetObjectItem(j,"PlanBrief"),s->brief);
 | ||
|   s->slave_soft_versions=jarray_to_list(cJSON_GetObjectItem(j,"CheckSoftVersion"),obj_int());
 | ||
|   s->slave_hard_versions=jarray_to_list(cJSON_GetObjectItem(j,"CheckHardVersion"),obj_int());
 | ||
|   JSON_GET_INT(cJSON_GetObjectItem(j,"TimeOutS"),s->timeout_s);
 | ||
|   JSON_GET_INT(cJSON_GetObjectItem(j,"TimeOutM"),s->timeout_m);
 | ||
|   JSON_GET_INT(cJSON_GetObjectItem(j,"TaskIDMax"),s->task_id_max);
 | ||
|   s->errs=jarray_to_list(cJSON_GetObjectItem(j,"MajorErrInfo"),obj_errcode());
 | ||
|   s->tasks=jarray_to_list(cJSON_GetObjectItem(j,"TaskArray"),obj_task());
 | ||
|   return s;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| static int _list_del_scheme(void *p)
 | ||
| {
 | ||
|   scheme_def *t=p;
 | ||
|   CHECK_DO(t->brief,free);
 | ||
|   CHECK_DO(t->slave_soft_versions,list_delete);
 | ||
|   CHECK_DO(t->slave_hard_versions,list_delete);
 | ||
|   CHECK_DO(t->errs,list_delete);
 | ||
|   CHECK_DO(t->tasks,list_delete);
 | ||
|   CHECK_DO(t->ch_errcode,list_delete);
 | ||
|   return 0;
 | ||
| }
 | ||
| 
 | ||
| static obj_def g_obj_scheme={
 | ||
|   .obj_size=sizeof(scheme_def),
 | ||
|   .to_obj_fun=_json_to_scheme,
 | ||
|   .del_fun=free,
 | ||
|   .sub=0,
 | ||
|   .del=_list_del_scheme
 | ||
| };
 | ||
| 
 | ||
| 
 | ||
| obj_def *obj_scheme(void)
 | ||
| {
 | ||
|   return &g_obj_scheme;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| scheme_def *json_to_scheme(cJSON *j)
 | ||
| {
 | ||
|   param_check(j);
 | ||
|   obj_def *obj=obj_scheme();
 | ||
|   scheme_def *s=obj->to_obj_fun(j);
 | ||
|   return s;
 | ||
| }
 | ||
| void scheme_delete(scheme_def *s)
 | ||
| {
 | ||
|   obj_def *obj=obj_scheme();
 | ||
|   param_check(s);
 | ||
|   obj->del(s);
 | ||
|   obj->del_fun(s);
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| // 任务id转化为字节数据
 | ||
| #define TASKSID_MAX_SIZE 0x100
 | ||
| static array_def *scheme_taskid_to_array(scheme_def *s)
 | ||
| {
 | ||
|   param_check(s);
 | ||
|   array_def *res=arr_creat();
 | ||
|   param_check(res);
 | ||
|   arr_append(res,s->plan_id&0xff);
 | ||
|   arr_append(res,(s->plan_id>>8)&0xff);
 | ||
|   arr_append(res,(s->plan_id>>16)&0xff);
 | ||
|   arr_append(res,(s->plan_id>>24)&0xff);
 | ||
|   for(int i=0;i<list_length(s->tasks);i++)
 | ||
|   {
 | ||
|     sch_task *t=list_get(s->tasks,i);
 | ||
|     arr_append(res,t->task_id);
 | ||
|   }
 | ||
|   int size=arr_length(res);
 | ||
|   if(size<TASKSID_MAX_SIZE){
 | ||
|     arr_append_num(res,TASKSID_MAX_SIZE-size,0xff);
 | ||
|   }else{
 | ||
|     DBG_WARN("taskid array size too larg.");
 | ||
|   }
 | ||
|   return res;
 | ||
| }
 | ||
| 
 | ||
| // 任务转化为字节数据
 | ||
| #define TASKS_MAX_SIZE (0x700-4)
 | ||
| static array_def *scheme_tasks_to_array(scheme_def *s)
 | ||
| {
 | ||
|   param_check(s);
 | ||
|   array_def *res=arr_creat();
 | ||
|   param_check(res);
 | ||
|   for(int i=0;i<list_length(s->tasks);i++)
 | ||
|   {
 | ||
|     sch_task *t=list_get(s->tasks,i);
 | ||
|     array_def *a=task_to_array(t);
 | ||
|     arr_appends_from(res,a);
 | ||
|     arr_delete(a);
 | ||
|   }
 | ||
|   int size=arr_length(res);
 | ||
|   if(size<TASKS_MAX_SIZE)
 | ||
|   {
 | ||
|     arr_append_num(res,TASKS_MAX_SIZE-size,0xff);
 | ||
|   }else{
 | ||
|     DBG_WARN("tasks array size too larg.");
 | ||
|   }
 | ||
|   return res;
 | ||
| }
 | ||
| 
 | ||
| // 方案转化为字节数据
 | ||
| array_def *scheme_to_byte_array(scheme_def *s)
 | ||
| {
 | ||
|   param_check(s);
 | ||
|   array_def *res=arr_creat();
 | ||
|   param_check(res);
 | ||
|   array_def *src;
 | ||
|   src=scheme_taskid_to_array(s);
 | ||
|   arr_appends_from(res,src);
 | ||
|   arr_delete(src);
 | ||
|   src=scheme_tasks_to_array(s);
 | ||
|   arr_appends_from(res,src);
 | ||
|   arr_delete(src);
 | ||
|   return res;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| // 统计返回数据长度
 | ||
| int scheme_get_returns_num(scheme_def *s)
 | ||
| {
 | ||
|   int num=0;
 | ||
|   for(int i=0;i<list_length(s->tasks);i++)
 | ||
|   {
 | ||
|     sch_task *t=list_get(s->tasks,i);
 | ||
|     num+=t->return_num;
 | ||
|   }
 | ||
|   return num;
 | ||
| }
 | ||
| 
 | ||
| // 返回0成功,1失败
 | ||
| int scheme_check_ack(array_def *data,int index)
 | ||
| {
 | ||
|   param_check(index>=0);
 | ||
|   param_check(index<arr_length(data)*8);
 | ||
|   uint8_t temp=arr_get(data,index/8);
 | ||
|   if((temp&(1<<(index%8)))!=0)
 | ||
|   {return 1;}else{return 0;}
 | ||
| }
 | ||
| 
 | ||
| // 返回子错误所在的主错误,失败返回0
 | ||
| int scheme_fine_majercode(scheme_def *s,int subcode)
 | ||
| {
 | ||
|   for(int i=0;i<list_length(s->errs);i++)
 | ||
|   {
 | ||
|     sch_errcode *e=list_get(s->errs,i);
 | ||
|     if(errcode_in_range(e,subcode))
 | ||
|       return e->err;
 | ||
|   }
 | ||
|   return 0;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| // 判定检测数据
 | ||
| scheme_returns *scheme_check_returns(scheme_def *s,array_def *data)
 | ||
| {
 | ||
|   int size=0;
 | ||
|   size+=sizeof(scheme_returns);
 | ||
|   size+=sizeof(task_returns)*list_length(s->tasks);
 | ||
|   size+=sizeof(reurn_item)*scheme_get_returns_num(s);
 | ||
|   scheme_returns *res=malloc(size);
 | ||
|   param_check(res);
 | ||
|   memset(res,0,size);
 | ||
|   res->size=size;
 | ||
|   if(s->ch_errcode==0) s->ch_errcode= list_creat_int();
 | ||
|   list_clear(s->ch_errcode);
 | ||
|   
 | ||
|   int start=16;
 | ||
|   int off=0;
 | ||
|   for(int i=0;i<list_length(s->tasks);i++)
 | ||
|   {
 | ||
|     int ack=scheme_check_ack(data,i);
 | ||
|     sch_task *t=list_get(s->tasks,i);
 | ||
|     array_def *arr_temp=arr_mid(data,start,t->return_num*2);
 | ||
|     task_returns *task_ret=task_check_returns(t,ack,arr_temp);
 | ||
|     arr_delete(arr_temp);
 | ||
|     memcpy(&res->data[off],task_ret,task_ret->size);
 | ||
|     off+=task_ret->size;
 | ||
|     start+=t->return_num*2;
 | ||
|     list_append_from(s->ch_errcode,t->ch_errcode);
 | ||
|   }
 | ||
|   if(list_length(s->ch_errcode)>0)
 | ||
|   {
 | ||
|     res->errcode=scheme_fine_majercode(s,list_get_int(s->ch_errcode,0));
 | ||
|   }else{
 | ||
|     res->errcode=0;
 | ||
|   }
 | ||
|   return res;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | 
