/**
 * \file    usbpd_hook.h
 * \brief   
 * 
 * \par     Copyright (c) 2018 UWE Technologies Corp., Ltd. All Rights Reserved.
 * \author  James
 * \date    2018-08-31
 * \version 
 * 
 * \history 
 *  Date        Note
 *  2018-08-31  Original Creation
 * 
 */
 
#ifndef __USBPD_HOOK_H_
#define __USBPD_HOOK_H_

#include "prl_msg_defs.h"
#include "usbpd_defs.h"


#define usbpd_cc_hook_declarer(role,state) \
v_func_v_ptr_t gp_usbpd_##role##_##state##_hook = NULL;

#define usbpd_cc_hook_extern(role,state) \
extern v_func_v_ptr_t gp_usbpd_##role##_##state##_hook;

usbpd_cc_hook_extern(snk,unattached);
usbpd_cc_hook_extern(snk,attachwait);
usbpd_cc_hook_extern(snk,attached);
usbpd_cc_hook_extern(src,unattached);
usbpd_cc_hook_extern(src,attachwait);
usbpd_cc_hook_extern(src,attached);

#define usbpd_cc_hook_set(role,state,vfunc) \
    do { \
        gp_usbpd_##role##_##state##_hook = vfunc; \
    } while(0)

#define usbpd_cc_hook(role,state) \
    do { \
        if (NULL != gp_usbpd_##role##_##state##_hook) \
        { \
            gp_usbpd_##role##_##state##_hook(); \
        } \
    } while(0)



extern s_func_v_ptr_t gp_usbpd_snk_transit_to_new_power_hook;

/** \brief Initialize hook: PD hook while sink mode require new power transition
 */
#define usbpd_snk_transit_to_new_power_hook_set(vfunc) \
    do { \
        gp_usbpd_snk_transit_to_new_power_hook = vfunc; \
    } while(0)

/** \brief Call PD hook while sink mode require new power transition
 */
#define usbpd_snk_transit_to_new_power_hook() \
    ((NULL != gp_usbpd_snk_transit_to_new_power_hook) ? gp_usbpd_snk_transit_to_new_power_hook() : S_ERROR)


extern s_func_ptr_t gp_usbpd_src_transit_to_new_power_hook;

/** \brief Initialize hook: PD hook while source mode require new power transition
 */
#define usbpd_src_transit_to_new_power_hook_set(vfunc) \
    do { \
        gp_usbpd_src_transit_to_new_power_hook = vfunc; \
    } while(0)

/** \brief Call PD hook while source mode require new power transition
 */
#define usbpd_src_transit_to_new_power_hook(arg) \
    ((NULL != gp_usbpd_src_transit_to_new_power_hook) ? gp_usbpd_src_transit_to_new_power_hook(arg) : S_ERROR)


#define usbpd_hook_declarer(name) \
v_func_b_ptr_t gp_usbpd_##name##_hook = NULL;

#define usbpd_hook_extern(name) \
extern v_func_b_ptr_t gp_usbpd_##name##_hook;

usbpd_hook_extern(src_vbus_en);
usbpd_hook_extern(discharge_en);
usbpd_hook_extern(cc1_vconn_en);
usbpd_hook_extern(cc2_vconn_en);
usbpd_hook_extern(rd_asserted_req);
usbpd_hook_extern(rp_asserted_req);

#define usbpd_hook_is_valid(name) \
    ((NULL != gp_usbpd_##name##_hook) ? TRUE : FALSE)


#define usbpd_hook_set(name,vfunc) \
    do { \
        gp_usbpd_##name##_hook = vfunc; \
    } while(0)

#define usbpd_hook(name,arg) \
    do { \
        if (NULL != gp_usbpd_##name##_hook) \
        { \
            gp_usbpd_##name##_hook(arg); \
        } \
    } while(0)


#define usbpd_hook_with_return_declarer(name) \
b_func_v_ptr_t gp_usbpd_with_return_##name##_hook = NULL;

#define usbpd_hook_with_return_extern(name) \
extern b_func_v_ptr_t gp_usbpd_with_return_##name##_hook;

usbpd_hook_with_return_extern(src_vbus_en);
usbpd_hook_with_return_extern(discharge_en);
usbpd_hook_with_return_extern(cc1_vconn_en);
usbpd_hook_with_return_extern(cc2_vconn_en);
usbpd_hook_with_return_extern(c1_vbus_volt);



#define usbpd_hook_with_return_set(name,vfunc) \
    do { \
        gp_usbpd_with_return_##name##_hook = vfunc; \
    } while(0)

#define usbpd_hook_with_return(name) \
    ((NULL != gp_usbpd_with_return_##name##_hook) ? gp_usbpd_with_return_##name##_hook() : FALSE)
#define usbpd_hook_with_return_is(name) \
    ((NULL != gp_usbpd_with_return_##name##_hook) ? TRUE:FALSE)

#define usbpd_event_hook_declarer(name) \
v_func_ptr_t gp_usbpd_event_##name##_hook = NULL;

#define usbpd_event_hook_extern(name) \
extern v_func_ptr_t gp_usbpd_event_##name##_hook;


usbpd_event_hook_extern(prs_started);
usbpd_event_hook_extern(prs_completed);
usbpd_event_hook_extern(drs_started);
usbpd_event_hook_extern(drs_completed);
usbpd_event_hook_extern(vcs_started);
usbpd_event_hook_extern(vcs_completed);
usbpd_event_hook_extern(power_change_req);
usbpd_event_hook_extern(idle);
usbpd_event_hook_extern(vdm_disc_ident_ack_received);
usbpd_event_hook_extern(vdm_ack_modal_opr_supp);
usbpd_event_hook_extern(prl_msg_received);
usbpd_event_hook_extern(prl_msg_sent);
usbpd_event_hook_extern(prl_msg_special);
usbpd_event_hook_extern(vdm_spec_cmd_fst);




#define usbpd_event_hook_set(name,vfunc) \
    do { \
        gp_usbpd_event_##name##_hook = vfunc; \
    } while(0)

#define usbpd_event_hook(name,arg) \
    do { \
        if (NULL != gp_usbpd_event_##name##_hook) \
        { \
            gp_usbpd_event_##name##_hook(arg); \
        } \
    } while(0)



#define usbpd_prl_msg_hook_declarer(type) \
v_func_args_ptr_t gp_usbpd_prl_msg_##type##_hook = NULL;

#define usbpd_prl_msg_hook_extern(type) \
extern v_func_args_ptr_t gp_usbpd_prl_msg_##type##_hook;

#define usbpd_prl_msg_hook_set(type,vfunc) \
    do { \
        gp_usbpd_prl_msg_##type##_hook = vfunc; \
    } while(0)

#define usbpd_prl_msg_hook(type,arg1,arg2) \
    do { \
        if (NULL != gp_usbpd_prl_msg_##type##_hook) \
        { \
            gp_usbpd_prl_msg_##type##_hook(arg1,arg2); \
        } \
    } while(0)
        
usbpd_prl_msg_hook_extern(vdm_spec_cmd_receive);
usbpd_prl_msg_hook_extern(vdm_spec_cmd_req);
usbpd_prl_msg_hook_extern(source_capabilities);
usbpd_prl_msg_hook_extern(request);
usbpd_prl_msg_hook_extern(sink_capabilities);
usbpd_prl_msg_hook_extern(vdm_disc_ident_req);
usbpd_prl_msg_hook_extern(vdm_disc_ident_resp);
usbpd_prl_msg_hook_extern(vdm_disc_svid_req);
usbpd_prl_msg_hook_extern(vdm_disc_svid_resp);
usbpd_prl_msg_hook_extern(vdm_disc_mode_req);
usbpd_prl_msg_hook_extern(vdm_disc_mode_resp);
usbpd_prl_msg_hook_extern(vdm_enter_mode_req);
usbpd_prl_msg_hook_extern(vdm_enter_mode_resp);
usbpd_prl_msg_hook_extern(vdm_exit_mode_req);
usbpd_prl_msg_hook_extern(vdm_exit_mode_resp);
usbpd_prl_msg_hook_extern(vdm_attention);
usbpd_prl_msg_hook_extern(vdm_svid_spec_cmd);
usbpd_prl_msg_hook_extern(vdm_unstructured);

usbpd_prl_msg_hook_extern(alert);
usbpd_prl_msg_hook_extern(get_country_info);
usbpd_prl_msg_hook_extern(battery_status);
usbpd_prl_msg_hook_extern(ext_src_cap);
usbpd_prl_msg_hook_extern(ext_status);
usbpd_prl_msg_hook_extern(ext_get_bat_cap);
usbpd_prl_msg_hook_extern(ext_get_bat_status);
usbpd_prl_msg_hook_extern(ext_bat_cap);
usbpd_prl_msg_hook_extern(ext_get_mfr_info);
usbpd_prl_msg_hook_extern(ext_mfr_info);
usbpd_prl_msg_hook_extern(ext_secur_req);
usbpd_prl_msg_hook_extern(ext_secur_resp);
usbpd_prl_msg_hook_extern(ext_fw_up_req);
usbpd_prl_msg_hook_extern(ext_fw_up_resp);
usbpd_prl_msg_hook_extern(ext_pps_status);
usbpd_prl_msg_hook_extern(ext_country_info);
usbpd_prl_msg_hook_extern(ext_country_codes);
usbpd_prl_msg_hook_extern(ext_snk_cap);

#endif /* #ifndef __USBPD_HOOK_H_ */

