#ifndef __OMW_SVC_H__
#define __OMW_SVC_H__

#ifdef __cplusplus
 extern "C" {
#endif

#include "host/adv.h"
#include "host/conn.h"
#include "host/gatt.h"
#include "host/att.h"

#define OMW_SVC_MAX_NUM  8

typedef void (* omw_svc_rx_cb)(const uint8_t * data, uint16_t len);
typedef const uint8_t * (* omw_svc_tx_cb)(uint16_t * len);

typedef void (* omw_svc_reg_xfer_cb)(omw_svc_rx_cb, omw_svc_tx_cb);
//cn_hdl: conection handler,  0 for all connections
typedef int (* omw_svc_notify_send_cb)(uint32_t cn_hdl, const uint8_t * data, uint16_t len);

#ifdef OMW_BLE_2G4_COEXIST
#include "t100x_2g4_def.h"

typedef void (* OMW_COE_TX_END_CB)();
typedef void (* OMW_COE_RX_END_CB)(uint8_t is_sync_it, uint8_t sync_ok, uint8_t crc_ok);

void omw_svc_coe_init();
void omw_svc_coe_init_ext(omw_2g4_param_t * param);

void omw_svc_coe_tx_rx_stop();
uint8_t omw_svc_coe_is_idle();

//return val: 0 ok, 1 pre tx/rx not finished, 2 is not ble non-connectable adv data, 3 tx len is 0 or > 39 bytes
uint8_t omw_svc_coe_tx_2g4_data(uint16_t chl, uint8_t * tx_buf, uint8_t to_tx_len, OMW_COE_TX_END_CB tx_end_cb);
uint8_t omw_svc_coe_tx_2g4_data_ext(uint16_t chl, uint8_t whiten_val, uint8_t * tx_buf, uint8_t to_tx_len, OMW_COE_TX_END_CB tx_end_cb);

//sync_to: time to wait for sync ok, ms
//return val: 0 ok, 1 pre tx/rx not finished
uint8_t omw_svc_coe_rx_2g4_data(uint16_t chl, uint16_t sync_to, uint8_t * rx_buf, OMW_COE_RX_END_CB rx_end_cb);
uint8_t omw_svc_coe_rx_2g4_data_ext(uint16_t chl, uint8_t whiten_val, uint16_t sync_to, uint8_t * rx_buf, uint16_t rx_len, OMW_COE_RX_END_CB rx_end_cb);
void omw_svc_coe_set_msb_first(uint8_t en);
int omw_svc_coe_set_last_n_preamble(uint8_t * lst_prm_val, uint8_t len);
#endif

typedef struct {
    void * svc_data_addr;
    void * svc_adv_data_addr;
    void * svc_scan_rsp_data_addr;

    uint8_t  svc_adv_data_len;
    uint8_t  svc_scan_rsp_data_len;
    uint16_t  rsved;

    omw_svc_reg_xfer_cb xfer_reg_cb;   //reg rx/tx cb
    omw_svc_notify_send_cb nt_tx_cb;   //notfity tx cb
}omw_svc_info_t;

extern uint8_t tx_enabled;

extern uint8_t omw_svc_num;
extern void * omw_sevice_list[];

extern void (* omw_svc_spec_cnnt_cb)(void);
extern void (* omw_svc_spec_dcnt_cb)(void);

void omw_app_connected_cb(uint32_t conn_handle, uint16_t cintlv, uint16_t cintlv_min, uint16_t cintlv_max);
void omw_app_disconnected_cb(uint32_t conn_handle, uint8_t reason);
void omw_app_rx_process_cb(const uint8_t * buf, uint16_t len);

void omw_svc_set_addr(uint8_t addr[6]);
void omw_svc_active_addr(uint8_t addr_type);

void omw_svc_add_base_svc(const void * p_svc);
//success: return 0,  -1: previous adv alread started, stop firstly, -2: > max svc num
int omw_svc_add_svc(const omw_svc_info_t * p_svc_info);

//num of 625us
void omw_svc_set_adv_intvl(uint16_t min, uint16_t max);
void omw_svc_set_adv_type(uint8_t type);
void omw_svc_set_adv_addr(uint8_t addr_type, bt_addr_le_t * dir_addr_info);
void omw_svc_set_adv_chl_map(uint8_t cm);
void omw_svc_set_adv_filter_plc(uint8_t fplc);

uint8_t omw_svc_get_adv_raw_data(uint8_t * buf);

#define omw_svc_set_adv_data  omw_set_adv_data
void omw_set_adv_data(void * padv_data, uint8_t len);

#define omw_svc_set_scan_rsp_data omw_set_scan_rsp_data
void omw_set_scan_rsp_data(void * pscr_data, uint8_t len);

//-1 previous adv alread started, stop firstly. 0: success
int omw_svc_start_adv(void);
int omw_svc_start_svc_adv(const omw_svc_info_t * p_svc_info);
uint8_t omw_svc_is_adv_enabled();

void omw_svc_stop_adv(void);
void omw_svc_disconnect(uint32_t handle);

int omw_rf_get_rssi(void);
// int omw_svc_get_last_rssi(uint32_t handle);
#define omw_svc_get_last_rssi omw_rf_get_rssi

//int db: -25dbm ~ 12dbm
int omw_rf_set_tx_pwr_lvl(int db);
void omw_rf_set_high_perf(uint8_t en);

//tm: nr of us
void omw_set_xtal_stup_tm(uint32_t tm);

//cnt_intvl_min, cnt_intvl_max:  number of 1.25ms
//cnt_to:  ms
int omw_svc_updata_cnnt_param(uint32_t handle, uint16_t cnt_intvl_min, uint16_t cnt_intvl_max, uint16_t lt, uint16_t  cnt_to);
void omw_svc_ccc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value);

void omw_svc_set_wkup_prep_tm(uint16_t cycles_32k);
void omw_svc_set_dev_sca(uint16_t new_sca);

#ifdef __cplusplus
}
#endif
#endif
