#ifndef __OMW_SVC_H__
#define __OMW_SVC_H__

#ifdef __cplusplus
 extern "C" {
#endif

#ifdef OMW_BLE_HOST_V0
#include "host/adv.h"
#include "host/conn.h"
#include "host/gatt.h"
#include "host/att.h"
#else
#ifndef bt_addr_le_t
typedef struct
{
    uint8_t type;
    bt_addr_t a;
} bt_addr_le_t;
#endif

#define omw_svc_get_battery_level()    bt_bas_get_battery_level()
#define omw_svc_set_battery_level(lvl) bt_bas_set_battery_level(lvl)
#endif

#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 hc_app_connected_cb(uint32_t conn_handle, uint16_t cintlv, uint16_t cintlv_min, uint16_t cintlv_max);
void hc_app_disconnected_cb(uint32_t conn_handle, uint8_t reason);
void hc_app_rx_process_cb(const uint8_t * buf, uint16_t len);

void omw_svc_set_addr(uint8_t addr[6]);

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);
void omw_set_adv_data(void * padv_data, uint8_t len);
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);

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

int omw_svc_get_last_rssi(uint32_t handle);

// void omw_svc_set_tx_pwr(int8_t pwr);
int omw_rf_set_tx_pwr_lvl(int db);

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

#ifdef CONFIG_BT_CENTRAL
#ifdef OMW_BLE_V0_2_0
#include "scan.h"
#include "initial_scan.h"
#endif

typedef void(* omw_svc_disc_svc_cb)(uint32_t cn_hdl, uint16_t attr_hdl, const struct bt_uuid * uuid);
typedef void(* omw_notify_cb)(uint32_t cn_hdl, const void *data, uint16_t length);

/* type value:
    * 0000b - legacy 1M passive
    * 0001b - legacy 1M active
    * 0010b - Ext. 1M passive
    * 0011b - Ext. 1M active
    * 0100b - invalid
    * 0101b - invalid
    * 0110b - invalid
    * 0111b - invalid
    * 1000b - Ext. Coded passive
    * 1001b - Ext. Coded active
    */
void omw_svc_set_scan_type(uint8_t sctp);
void omw_svc_set_scan_addr(bt_addr_le_t * peer_addr_info, uint8_t own_addr_type);
void omw_svc_set_scan_intvl_win(uint16_t scan_interval, uint16_t scan_window);
void omw_svc_set_scan_filt_pol(uint8_t filter_policy);
void omw_svc_set_scan_conn_param(uint16_t conn_interval_min, uint16_t conn_interval_max, uint16_t conn_latency, uint16_t supervision_timeout,
    uint16_t min_ce_len, uint16_t max_ce_len);

//void omw_svc_reg_scan_cb(bt_le_scan_cb_t cb);
#define omw_svc_reg_scan_cb bt_scan_register_cb
#define omw_write_rsp_cb bt_gatt_write_func_t

int omw_svc_start_scan(void);
int omw_svc_start_scan_and_conn(void);
void omw_svc_stop_scan(void);

int omw_svc_subscribe(uint32_t cn_hdl, uint16_t val_hdl, uint16_t ccc_hdl, uint16_t ntf_val, omw_notify_cb ntf_cb);
int omw_svc_disc_svc(uint32_t cn_hdl, uint16_t st_hld, uint16_t ed_hld, struct bt_uuid * uuid, uint8_t type, omw_svc_disc_svc_cb dc_cb);

int omw_svc_write(uint32_t cn_hdl, uint16_t wt_hdl, void * data, uint16_t len, uint8_t sign, omw_write_rsp_cb rsp_cb);
int omw_svc_read(uint32_t cn_hdl, struct bt_uuid * uuid);

#endif

#ifdef __cplusplus
}
#endif
#endif
