#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);

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_svc_get_last_rssi(uint32_t handle);

//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
