
#ifndef J1939_DTC_C_
#define J1939_DTC_C_

#include"j1939_dtc.h"
#include"j1939_queue.h"
//#include "RTE_APP.h"
#include "j1939_tools.h"

#define J1939_DTC_TX_DATA_LEN   50
static J1939Msg j1939_dtc_tx_msg;
static uint8_T j1939_dtc_tx_data[J1939_DTC_TX_DATA_LEN];
//******函数声明******//
J1939DtcItem*  J1939_PAGED j1939_dtc_add_dtc(J1939Context* J1939_PAGED context, J1939DtcInfo* J1939_PAGED dtc_info);
J1939Result j1939_dtc_trouble_on_update(J1939DtcItem* J1939_PAGED item, J1939DtcInfo* J1939_PAGED dtc_info);
uint8_T j1939_dtc_dtc_send_check_with_item(J1939DtcItem* J1939_PAGED item);
J1939Result j1939_dtc_all_dtc_send(J1939Context* J1939_PAGED context, uint16_T* dtc_cnt);
J1939DtcItem* J1939_PAGED j1939_dtc_search_dtc_item(J1939Context* J1939_PAGED context, J1939DtcInfo* J1939_PAGED dtc_info);
J1939Result j1939_dtc_trouble_off_update(J1939DtcItem* J1939_PAGED item, J1939DtcInfo* J1939_PAGED dtc_info);
uint8_T j1939_dtc_dtc_none_send_check(J1939Context* J1939_PAGED context);
void j1939_dtc_clear_dtc_one_second_cnt(J1939Context* J1939_PAGED context);
void j1939_dtc_oc_last_second_update(J1939Context* J1939_PAGED context);

/*****************************************************************************
 *函数名称:J1939_DTCInit
 *函数功能:J1939DTC初始化
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *返 回 值:J1939_OK 成功,其他失败
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
J1939Result J1939_DTCInit(J1939Context* J1939_PAGED context)
{
	//传参错误
    if(context == NULL)
    {
    	return J1939_ERR;
    }
    
    context->dtc_context.dtc_item_max = J1939_DTC_MAX;

    context->dtc_context.dtc_item_start = context->dtc_context.dtc_item_buff;
    
    context->dtc_context.is_start = TRUE;
    j1939_dtc_tx_msg.data =  j1939_dtc_tx_data;
    j1939_dtc_tx_msg.msg_max_len =  J1939_DTC_TX_DATA_LEN;
    
    
    return J1939_OK;
}



/*****************************************************************************
 *函数名称:j1939_dtc_trouble_on
 *函数功能:J1939DTC故障开启
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *         J1939DtcInfo* J1939_PAGED dtc_info dtc信息
 *返 回 值:J1939_OK 成功,其他失败
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
J1939Result j1939_dtc_trouble_on(J1939Context* J1939_PAGED context, J1939DtcInfo* J1939_PAGED dtc_info)
{
    J1939Result res = J1939_OK;
    J1939DtcItem* J1939_PAGED item;
    
    if(context == NULL ||  dtc_info == NULL) 
    {
        return J1939_ERR;
    }
    
    item = j1939_dtc_add_dtc(context, dtc_info);
    
    if(item == NULL)
    {
    	return J1939_ERR;
    }
    
    if(j1939_dtc_trouble_on_update(item, dtc_info) != J1939_OK)
    {
    	return J1939_OK;
    }
    
    if(context->dtc_context.is_start && j1939_dtc_dtc_send_check_with_item(item))
    {
        res = j1939_dtc_all_dtc_send(context, NULL);
    
        if(res == J1939_OK)
        {
        	item->send_flag = 0;
        }
        else
        {
        	context->dtc_context.send_failure_flag = 1;
        }
    }
    context->dtc_context.occure_cnt_one_second++;
    
    return res;
}



/*****************************************************************************
 *函数名称:j1939_dtc_trouble_on_update
 *函数功能:J1939DTC故障更新
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *         J1939DtcInfo* J1939_PAGED dtc_info dtc信息
 *返 回 值:J1939_OK 成功,其他失败
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
J1939Result j1939_dtc_trouble_on_update(J1939DtcItem* J1939_PAGED item, J1939DtcInfo* J1939_PAGED dtc_info)
{
    uint8_T oc, oc_last_second;
    uint32_T now_tick;//, last_tick;
    
    if(item == NULL || dtc_info == NULL)
    {
    	return J1939_ERR;
    }
    
    oc = item->info.oc;
    oc_last_second = item->oc_last_second;
    now_tick = get_tick_count();
    //last_tick = item->last_tick;
    
    if(item->status == kDTCOn &&
      item->info.spn == dtc_info->spn &&
      item->info.fmi == dtc_info->fmi)
    {
    	return J1939_ERR;
    }
    
    item->info.spn = dtc_info->spn;
    item->info.fmi = dtc_info->fmi;
    item->info.cm = dtc_info->cm;
    if(item->info.oc < J1939_OC_MAX)
    {
    	item->info.oc++;
    }
    item->status = kDTCOn;
    item->last_tick = now_tick;
    
    if(oc_last_second == oc || //1秒内第一次触发故障
        oc_last_second == 0 || //此故障第一次发生
        now_tick % J1939_DTC_DM_BROADCAST_INTERVAL < J1939_DTC_DM_BROADCAST_INTERVAL - 10) //不与1秒发送冲突
    {
        item->send_flag = 1;
    }    
    return J1939_OK;
}


/*****************************************************************************
 *函数名称:j1939_dtc_dtc_send_check_with_item
 *函数功能:J1939DTC检测
 *参    数:J1939DtcItem* J1939_PAGED item
 *返 回 值:TRUE 成功,其他失败
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
uint8_T j1939_dtc_dtc_send_check_with_item(J1939DtcItem* J1939_PAGED item)
{
    if(item == NULL)
    {
    	return FALSE;
    }
    
    if(item->send_flag == 0)
    {
    	return FALSE;
    }
       
    return TRUE;
}


/*****************************************************************************
 *函数名称:j1939_dtc_dtc_send_check
 *函数功能:J1939DTC检测
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *返 回 值:TRUE 成功,其他失败
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
uint8_T j1939_dtc_dtc_send_check(J1939Context* J1939_PAGED context)
{
    J1939DtcItem* J1939_PAGED item;
    
    //传参错误
    if(context == NULL)
    {
    	return FALSE;
    }
    
    item = context->dtc_context.dtc_item_start;
    while(item)
    {
        if(item->send_flag)
        {
        	return TRUE;
        }
        
        item = (J1939DtcItem* J1939_PAGED)item->next;
    }   
    return FALSE;
}


/*****************************************************************************
 *函数名称:j1939_dtc_all_dtc_send
 *函数功能:J1939所有的dtc发送
 *参    数:J1939Context* J1939_PAGED context  J1939内容 uint16_T* dtc_cnt dtc计数
 *返 回 值:TRUE 成功,其他失败
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
J1939Result j1939_dtc_all_dtc_send(J1939Context* J1939_PAGED context, uint16_T* dtc_cnt)
{
    uint16_T index = 0, dtc_on_cnt = 0;
    J1939DtcItem* J1939_PAGED item;

    //传参错误
    if(context == NULL)
    {
    	return J1939_ERR;
    }
    
    j1939_dtc_tx_msg.id.value = ((uint32_T)J1939_DM1_PRI << 26)+((uint32_T)J1939_DM1_PGN << 8)+context->device_param.addr;

    j1939_dtc_tx_msg.source_addr = context->device_param.addr;
    j1939_dtc_tx_msg.pgn = J1939_DM1_PGN;

    J1939_WRITE_LT_INT8U_WITH_BUFF_SIZE(j1939_dtc_tx_msg.data, index, 0xFF, j1939_dtc_tx_msg.msg_max_len);
    J1939_WRITE_LT_INT8U_WITH_BUFF_SIZE(j1939_dtc_tx_msg.data, index, 0xFF, j1939_dtc_tx_msg.msg_max_len);
    
    item = context->dtc_context.dtc_item_start;
    while(item)
    {
        if(item->status == kDTCOn)
        {
            dtc_on_cnt++;
            WRITE_DTC(j1939_dtc_tx_msg, index, j1939_dtc_tx_msg.msg_max_len, item->info.spn, item->info.fmi, item->info.oc, item->info.cm)
        }
        item = (J1939DtcItem* J1939_PAGED)item->next;
    }
    if(dtc_cnt)
    {
    	*dtc_cnt = dtc_on_cnt;
    }
    if(dtc_on_cnt == 0)
    {
    	return J1939_OK;
    }
    
    j1939_dtc_tx_msg.msg_len = index;
    if(index > J1939_CAN_FRAME_DATA_LEN)    
    {
        j1939_dtc_tx_msg.id.Bits.PS = 0xFF; //广播
        j1939_dtc_tx_msg.dest_addr = 0xFF;
    }
    return J1939_TxMsg(context, &j1939_dtc_tx_msg);
}


/*****************************************************************************
 *函数名称:j1939_dtc_send_dtc_none
 *函数功能:J1939dtc发送
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *返 回 值:TRUE 成功,其他失败
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
J1939Result j1939_dtc_send_dtc_none(J1939Context* J1939_PAGED context)
{
    uint16_T index = 0;
    
    //传参错误
    if(context == NULL)
    {
    	return J1939_ERR;
    }
    
    j1939_dtc_tx_msg.id.value = ((uint32_T)J1939_DM1_PRI << 26)+((uint32_T)J1939_DM1_PGN << 8)+context->device_param.addr;

    j1939_dtc_tx_msg.source_addr = context->device_param.addr;
    j1939_dtc_tx_msg.pgn = J1939_DM1_PGN;

    J1939_WRITE_LT_INT8U_WITH_BUFF_SIZE(j1939_dtc_tx_msg.data, index, 0xFF, j1939_dtc_tx_msg.msg_max_len);
    J1939_WRITE_LT_INT8U_WITH_BUFF_SIZE(j1939_dtc_tx_msg.data, index, 0xFF, j1939_dtc_tx_msg.msg_max_len);
    WRITE_DTC_NONE(j1939_dtc_tx_msg, index, j1939_dtc_tx_msg.msg_max_len)
    j1939_dtc_tx_msg.msg_len = index;
    if(index > J1939_CAN_FRAME_DATA_LEN)    
    {
        j1939_dtc_tx_msg.id.Bits.PS = 0xFF; //广播
        j1939_dtc_tx_msg.dest_addr = 0xFF;
    }
    return J1939_TxMsg(context, &j1939_dtc_tx_msg);
}


/*****************************************************************************
 *函数名称:j1939_dtc_trouble_off
 *函数功能:J1939dtc问题关闭更新
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *         J1939DtcInfo* J1939_PAGED dtc_info dtc信息
 *返 回 值:TRUE 成功,其他失败
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
J1939Result j1939_dtc_trouble_off(J1939Context* J1939_PAGED context, J1939DtcInfo* J1939_PAGED dtc_info)
{
    J1939Result res = J1939_OK;
    J1939DtcItem* J1939_PAGED item;
    
    //传参错误
    if(context == NULL || dtc_info == NULL)
    {
    	return J1939_ERR;
    }
    
    //查找DTC
    item = j1939_dtc_search_dtc_item(context, dtc_info);
    
    if(item == NULL)
    {
    	return J1939_ERR;
    }
    
    //dtc故障关闭
    if(j1939_dtc_trouble_off_update(item, dtc_info) != J1939_OK)
    {
    	return J1939_OK;
    }
    
    context->dtc_context.release_cnt_one_second++;
    if(context->dtc_context.is_start == 0)
    {
    	return J1939_OK;
    }
    
    //DTC检测
    if(j1939_dtc_dtc_none_send_check(context)) 
    {
        res = j1939_dtc_send_dtc_none(context);
        context->dtc_context.release_cnt_one_second = 0;
    }
    else
    {
        if(context->dtc_context.occure_cnt_one_second == 0)
        {
            if(j1939_dtc_all_dtc_send(context, NULL) != J1939_OK)
            {
                context->dtc_context.send_failure_flag = 1; //启动重发机制
            }
        }
    }   
    return res;
}


/*****************************************************************************
 *函数名称:j1939_dtc_trouble_off_update
 *函数功能:J1939dtc故障关闭
 *参    数:J1939Context* J1939_PAGED item  J1939item
 *         J1939DtcInfo* J1939_PAGED dtc_info dtc信息
 *返 回 值:TRUE 成功,其他失败
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
J1939Result j1939_dtc_trouble_off_update(J1939DtcItem* J1939_PAGED item, J1939DtcInfo* J1939_PAGED dtc_info)
{
	//传参错误
    if(item == NULL || dtc_info == NULL)
    {
    	return J1939_ERR;
    }
    
    if(item->status == kDTCOff &&
        item->info.spn == dtc_info->spn &&
        item->info.fmi == dtc_info->fmi)
    {
    	return J1939_ERR;
    }
    
    item->info.spn = dtc_info->spn;
    item->info.fmi = dtc_info->fmi;
    item->info.cm = dtc_info->cm;
    item->status = kDTCOff;
    item->last_tick = get_tick_count();
    
    return J1939_OK;
}


/*****************************************************************************
 *函数名称:j1939_dtc_get_dtc_on_num
 *函数功能:获取dtc的故障个数
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *返 回 值:dtc_on_cnt--dtc个数
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
uint16_T j1939_dtc_get_dtc_on_num(J1939Context* J1939_PAGED context)
{
    uint16_T dtc_on_cnt = 0;
    J1939DtcItem* J1939_PAGED item;
    
    //传参错误
    if(context == NULL)
    {
    	return 0;
    }
    
    item = context->dtc_context.dtc_item_start;
    while(item)
    {
        if(item->status == kDTCOn)
        {
        	dtc_on_cnt++;
        }
        item = (J1939DtcItem* J1939_PAGED)item->next;
    }
    
    return dtc_on_cnt;
}



/*****************************************************************************
 *函数名称:j1939_dtc_dtc_none_send_check
 *函数功能:dtc检测
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *返 回 值:TRUE
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
uint8_T j1939_dtc_dtc_none_send_check(J1939Context* J1939_PAGED context)
{
	//传参错误
    if(context == NULL)
    {
    	return FALSE;
    }
    
    //dtc的故障个数
    if(j1939_dtc_get_dtc_on_num(context) != 0 ||
        context->dtc_context.occure_cnt_one_second != 0)
    {
    	return FALSE;
    }
    
    return TRUE;
}



/*****************************************************************************
 *函数名称:j1939_dtc_clear_all_dtc_send_flag
 *函数功能:清除所有的dtc发送标志
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *返 回 值:无
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
J1939Result j1939_dtc_clear_all_dtc_send_flag(J1939Context* J1939_PAGED context)
{
    J1939DtcItem* J1939_PAGED item;
    
    //传参错误
    if(context == NULL)
    {
    	return J1939_ERR;
    }
    
    item = context->dtc_context.dtc_item_start;
    while(item)
    {
        if(item->send_flag)
        {
        	item->send_flag = 0;
        }
        item = (J1939DtcItem* J1939_PAGED)item->next;
    }
    
    return J1939_OK;
}



/*****************************************************************************
 *函数名称:j1939_dtc_send_dm1_check
 *函数功能:发送DM1检测
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *返 回 值:无
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
void j1939_dtc_send_dm1_check(J1939Context* J1939_PAGED context, uint32_T tick)
{
    uint8_T one_second_flag = 0;
    uint16_T dtc_cnt;
    
    
    //传参错误
    if(context == NULL)
    {
    	return;
    }
    
    if(context->dtc_context.last_tick == 0)
    {
    	context->dtc_context.last_tick = tick / 1000 * 1000;
    }
    //周期更新
    if(get_interval_by_tick(context->dtc_context.last_tick, tick) >= J1939_DTC_DM_BROADCAST_INTERVAL)
    {
        context->dtc_context.last_tick = get_tick_count();
        one_second_flag = 1;
    }
    if(context->dtc_context.is_start == 0)
    {
    	return;
    }
    
    if(context->dtc_context.send_failure_flag == 1 ||
        one_second_flag)
    {
  
        //J1939所有的dtc发送失败
        if(j1939_dtc_all_dtc_send(context, &dtc_cnt) != J1939_OK)
        {
            context->dtc_context.send_failure_flag = 1;
 
            return;
        }
        (void)j1939_dtc_clear_all_dtc_send_flag(context);

        context->dtc_context.send_failure_flag = 0;
        
        if(dtc_cnt == 0 && context->dtc_context.release_cnt_one_second && one_second_flag) 
        {
            (void)j1939_dtc_send_dtc_none(context);
            context->dtc_context.release_cnt_one_second = 0;
        }
    }
    if(one_second_flag)
    {
    	//清除DTC
        j1939_dtc_clear_dtc_one_second_cnt(context);
        //更新时间
        j1939_dtc_oc_last_second_update(context);
    }
}



/*****************************************************************************
 *函数名称:j1939_dtc_clear_dtc_one_second_cnt
 *函数功能:清除dtc
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *返 回 值:无
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
void j1939_dtc_clear_dtc_one_second_cnt(J1939Context* J1939_PAGED context)
{
	//传参错误
    if(context == NULL)
    {
    	return;
    }
    
    context->dtc_context.occure_cnt_one_second = 0;
    context->dtc_context.release_cnt_one_second = 0;
}



/*****************************************************************************
 *函数名称:j1939_dtc_oc_last_second_update
 *函数功能:
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *返 回 值:无
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
void j1939_dtc_oc_last_second_update(J1939Context* J1939_PAGED context)
{
    J1939DtcItem* J1939_PAGED item;
    
    //传参错误
    if(context == NULL)
    {
    	return;
    }
    
    item = (J1939DtcItem* J1939_PAGED)context->dtc_context.dtc_item_start;
    while(item)
    {
        item->oc_last_second = item->info.oc;
        item = (J1939DtcItem* J1939_PAGED)item->next;
    }
}



/*****************************************************************************
 *函数名称:j1939_dtc_reset_all_dtc
 *函数功能:复位所有的dtc
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *返 回 值:J1939_OK
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
J1939Result j1939_dtc_reset_all_dtc(J1939Context* J1939_PAGED context)
{
    J1939DtcItem* J1939_PAGED item;
    
    //传参错误
    if(context == NULL)
    {
    	return J1939_ERR;
    }
    
    item = context->dtc_context.dtc_item_start;
    while(item)
    {
        if(item->status == kDTCOn)
        {
        	item->status = kDTCOff;
        }
        item = (J1939DtcItem* J1939_PAGED)item->next;
    }
    
    return J1939_OK;
}


/*****************************************************************************
 *函数名称:j1939_dtc_poll
 *函数功能:dtc轮询
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *返 回 值:dtc个数
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
void j1939_dtc_poll(J1939Context* J1939_PAGED context, uint32_T tick)
{
	//传参错误
    if(context == NULL)
    {
    	return;
    }
    
    if(context->dtc_context.is_start)
    {
    	//发送DM1检测
    	j1939_dtc_send_dm1_check(context, tick);
    }
}

/***************************************dtc_item_function*******************************************************/


/*****************************************************************************
 *函数名称:j1939_dtc_search_dtc_item
 *函数功能:查找dtc
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *         J1939DtcInfo* J1939_PAGED dtc_info dtc信息
 *返 回 值:dtc个数
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
J1939DtcItem* J1939_PAGED j1939_dtc_search_dtc_item(J1939Context* J1939_PAGED context, J1939DtcInfo* J1939_PAGED dtc_info)
{
    J1939DtcItem* J1939_PAGED item;
    
    //传参错误
    if(context == NULL || dtc_info == NULL)
    {
    	return NULL;
    }
    
    item = (J1939DtcItem* J1939_PAGED)context->dtc_context.dtc_item_start;
    while(item)
    {
        if(item->info.spn == dtc_info->spn/* && item->info.fmi == dtc_info->fmi*/)
        {
        	break;
        }
        
        item = (J1939DtcItem* J1939_PAGED)item->next;
    }   
    return item;
}



/*****************************************************************************
 *函数名称:j1939_dtc_get_dtc_item_head
 *函数功能:查找dtc的头
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *返 回 值:context->dtc_context.dtc_item_start
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
J1939DtcItem*  J1939_PAGED j1939_dtc_get_dtc_item_head(J1939Context* J1939_PAGED context)
{
	//传参错误
    if(context == NULL)
    {
    	return NULL;
    }
    
    return context->dtc_context.dtc_item_start;
}


/*****************************************************************************
 *函数名称:j1939_dtc_get_dtc_item_tail
 *函数功能:查找dtc的头
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *返 回 值:item
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
J1939DtcItem* J1939_PAGED j1939_dtc_get_dtc_item_tail(J1939Context* J1939_PAGED context)
{
    J1939DtcItem* J1939_PAGED item = NULL;
    
    //传参错误
    if(context == NULL)
    {
    	return NULL;
    }
    
    item = (J1939DtcItem* J1939_PAGED)context->dtc_context.dtc_item_start;
    if(item == NULL)
    {
    	return NULL;
    }
    
    while(item->next)
    {
        item = (J1939DtcItem* J1939_PAGED)item->next;
    }
    
    return item;
}



/*****************************************************************************
 *函数名称:j1939_dtc_get_free_dtc_item
 *函数功能:查找dtc空闲的
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *返 回 值:dtc尾部
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
J1939DtcItem*  J1939_PAGED j1939_dtc_get_free_dtc_item(J1939Context* J1939_PAGED context)
{
    uint8_T i, len = context->dtc_context.dtc_item_max;
    
    //传参错误
    if(context == NULL)
    {
    	return NULL;
    }
    
    for(i=0; i<len; i++)
    {
        if(context->dtc_context.dtc_item_buff[i].status == kDTCNone) 
        {
            return (J1939DtcItem*  J1939_PAGED)(&context->dtc_context.dtc_item_buff[i]);
        }
    }
    
    return NULL;
}



/*****************************************************************************
 *函数名称:j1939_dtc_reset_dtc_item
 *函数功能:j1939复位dtc
 *参    数:J1939DtcItem*  J1939_PAGED item  J1939项目
 *返 回 值:J1939_OK
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
J1939Result j1939_dtc_reset_dtc_item(J1939DtcItem*  J1939_PAGED item)
{
    if(item == NULL)
    {
    	return J1939_ERR;
    }
    
    (void)J1939_BufferSet((uint8_T* J1939_PAGED)item, 0, sizeof(J1939DtcItem));
    
    return J1939_OK;
}



/*****************************************************************************
 *函数名称:j1939_dtc_add_dtc_item
 *函数功能:j1939增加dtc
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *         J1939DtcItem*  J1939_PAGED item  J1939项目
 *返 回 值:J1939_OK
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
J1939Result j1939_dtc_add_dtc_item(J1939Context* J1939_PAGED context, J1939DtcItem*  J1939_PAGED item)
{
    J1939DtcItem* J1939_PAGED tail_item;
    
    if(context == NULL || item == NULL)
    {
    	return J1939_ERR;
    }
    
    tail_item = j1939_dtc_get_dtc_item_tail(context);
    if(tail_item == NULL)
    {
    	return J1939_ERR;
    }
    
    if(tail_item != item)
    {
    	tail_item->next = (LIST_ITEM* J1939_PAGED)item;
    }
    item->next = NULL;
    context->dtc_context.dtc_item_cnt++;
    
    return J1939_OK;
}



/*****************************************************************************
 *函数名称:j1939_dtc_remove_dtc_item
 *函数功能:j1939移除dtc
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *         J1939DtcItem*  J1939_PAGED item  J1939项目
 *返 回 值:J1939_OK
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
J1939Result j1939_dtc_remove_dtc_item(J1939Context* J1939_PAGED context, J1939DtcItem*  J1939_PAGED item)
{
    J1939DtcItem*  J1939_PAGED header_item;
    J1939DtcItem* J1939_PAGED tail_item;
    
    //传参错误
    if(context == NULL || item == NULL)
    {
    	return J1939_ERR;
    }
    
    //查找dtc的头
    header_item = j1939_dtc_get_dtc_item_head(context);
    if(header_item == NULL)
    {
    	return J1939_ERR;
    }
    
    tail_item = j1939_dtc_get_dtc_item_tail(context);
    if(tail_item == NULL)
    {
    	return J1939_ERR;
    }
    
    while ((J1939DtcItem*  J1939_PAGED)(header_item->next) != item && header_item->next != NULL)
    {
    	header_item = (J1939DtcItem*  J1939_PAGED)(header_item->next);
    }
    if ((J1939DtcItem*  J1939_PAGED)(header_item->next) == item)
    {
    	header_item->next = item->next;
    }
    
    return J1939_OK;
}



/*****************************************************************************
 *函数名称:j1939_dtc_add_dtc
 *函数功能:j1939增加dtc
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *         J1939DtcInfo* J1939_PAGED dtc_info dtc信息
 *返 回 值:free_item
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
J1939DtcItem*  J1939_PAGED j1939_dtc_add_dtc(J1939Context* J1939_PAGED context, J1939DtcInfo* J1939_PAGED dtc_info)
{
    J1939DtcItem* J1939_PAGED free_item;
    
    //传参错误
    if(context == NULL || dtc_info == NULL)
    {
    	return NULL;
    }
    
    //查找DTC
    free_item = j1939_dtc_search_dtc_item(context, dtc_info);
    if(free_item == NULL)
    {
        free_item = j1939_dtc_get_free_dtc_item(context);
        if(free_item == NULL)
        {
        	return NULL;
        }
        //复位DTC
        (void)j1939_dtc_reset_dtc_item(free_item);
        //增加DTC
        (void)j1939_dtc_add_dtc_item(context, free_item);
    }
    return free_item;
}




/*****************************************************************************
 *函数名称:j1939_dtc_add_dtc
 *函数功能:j1939释放dtc
 *参    数:J1939Context* J1939_PAGED context  J1939内容
 *         J1939DtcInfo* J1939_PAGED dtc_info dtc信息
 *返 回 值:res
 *作    者:Admin
 *修订信息:
 ******************************************************************************/
J1939Result j1939_dtc_release_dtc(J1939Context* J1939_PAGED context, J1939DtcInfo* J1939_PAGED dtc_info)
{
    J1939Result res = J1939_OK;
    J1939DtcItem* J1939_PAGED item;
    
    //传参错误
    if(context == NULL || dtc_info == NULL)
    {
    	return J1939_ERR;
    }
    
    //查找DTC
    item = j1939_dtc_search_dtc_item(context, dtc_info);
    if(item == NULL)
    {
    	return J1939_OK;
    }
    
    //移除DTC
    res = j1939_dtc_remove_dtc_item(context, item);
    //复位DTC
    (void)j1939_dtc_reset_dtc_item(item);
    
    return res;
}

#endif
