/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_INCLUDE_BT_HH_H
#define ANDROID_INCLUDE_BT_HH_H

#include <stdint.h>
#include <string>

__BEGIN_DECLS

#define BTHH_MAX_DSC_LEN 884

/* HH connection states */
typedef enum {
  BTHH_CONN_STATE_CONNECTED = 0,
  BTHH_CONN_STATE_CONNECTING = 1,
  BTHH_CONN_STATE_DISCONNECTED = 2,
  BTHH_CONN_STATE_DISCONNECTING = 3,
  BTHH_CONN_STATE_UNKNOWN = 0xff,
} bthh_connection_state_t;

__END_DECLS
#define CASE_RETURN_TEXT(code) \
  case code:                   \
    return #code

inline std::string bthh_connection_state_text(
    const bthh_connection_state_t& state) {
  switch (state) {
    CASE_RETURN_TEXT(BTHH_CONN_STATE_CONNECTED);
    CASE_RETURN_TEXT(BTHH_CONN_STATE_CONNECTING);
    CASE_RETURN_TEXT(BTHH_CONN_STATE_DISCONNECTED);
    CASE_RETURN_TEXT(BTHH_CONN_STATE_DISCONNECTING);
    CASE_RETURN_TEXT(BTHH_CONN_STATE_UNKNOWN);
    default:
      return std::string("UNKNOWN[%u]", state);
  }
}
#undef CASE_RETURN_TEXT
__BEGIN_DECLS

typedef enum {
  BTHH_OK = 0,
  BTHH_HS_HID_NOT_READY,  /* handshake error : device not ready */
  BTHH_HS_INVALID_RPT_ID, /* handshake error : invalid report ID */
  BTHH_HS_TRANS_NOT_SPT,  /* handshake error : transaction not spt */
  BTHH_HS_INVALID_PARAM,  /* handshake error : invalid paremter */
  BTHH_HS_ERROR,          /* handshake error : unspecified HS error */
  BTHH_ERR,               /* general BTA HH error */
  BTHH_ERR_SDP,           /* SDP error */
  BTHH_ERR_PROTO,         /* SET_Protocol error,
                                                        only used in BTA_HH_OPEN_EVT
                             callback */
  BTHH_ERR_DB_FULL,       /* device database full error, used  */
  BTHH_ERR_TOD_UNSPT,     /* type of device not supported */
  BTHH_ERR_NO_RES,        /* out of system resources */
  BTHH_ERR_AUTH_FAILED,   /* authentication fail */
  BTHH_ERR_HDL
} bthh_status_t;

/* Protocol modes */
typedef enum {
  BTHH_REPORT_MODE = 0x00,
  BTHH_BOOT_MODE = 0x01,
  BTHH_UNSUPPORTED_MODE = 0xff
} bthh_protocol_mode_t;

/* Report types */
typedef enum {
  BTHH_INPUT_REPORT = 1,
  BTHH_OUTPUT_REPORT,
  BTHH_FEATURE_REPORT
} bthh_report_type_t;

typedef struct {
  int attr_mask;
  uint8_t sub_class;
  uint8_t app_id;
  int vendor_id;
  int product_id;
  int version;
  uint8_t ctry_code;
  int dl_len;
  uint8_t dsc_list[BTHH_MAX_DSC_LEN];
} bthh_hid_info_t;

/** Callback for connection state change.
 *  state will have one of the values from bthh_connection_state_t
 */
typedef void (*bthh_connection_state_callback)(RawAddress* bd_addr,
                                               bthh_connection_state_t state);

/** Callback for vitual unplug api.
 *  the status of the vitual unplug
 */
typedef void (*bthh_virtual_unplug_callback)(RawAddress* bd_addr,
                                             bthh_status_t hh_status);

/** Callback for get hid info
 *  hid_info will contain attr_mask, sub_class, app_id, vendor_id, product_id,
 * version, ctry_code, len
 */
typedef void (*bthh_hid_info_callback)(RawAddress* bd_addr,
                                       bthh_hid_info_t hid_info);

/** Callback for get protocol api.
 *  the protocol mode is one of the value from bthh_protocol_mode_t
 */
typedef void (*bthh_protocol_mode_callback)(RawAddress* bd_addr,
                                            bthh_status_t hh_status,
                                            bthh_protocol_mode_t mode);

/** Callback for get/set_idle_time api.
 */
typedef void (*bthh_idle_time_callback)(RawAddress* bd_addr,
                                        bthh_status_t hh_status, int idle_rate);

/** Callback for get report api.
 *  if staus is ok rpt_data contains the report data
 */
typedef void (*bthh_get_report_callback)(RawAddress* bd_addr,
                                         bthh_status_t hh_status,
                                         uint8_t* rpt_data, int rpt_size);

/** Callback for set_report/set_protocol api and if error
 *  occurs for get_report/get_protocol api.
 */
typedef void (*bthh_handshake_callback)(RawAddress* bd_addr,
                                        bthh_status_t hh_status);

/** BT-HH callback structure. */
typedef struct {
  /** set to sizeof(BtHfCallbacks) */
  size_t size;
  bthh_connection_state_callback connection_state_cb;
  bthh_hid_info_callback hid_info_cb;
  bthh_protocol_mode_callback protocol_mode_cb;
  bthh_idle_time_callback idle_time_cb;
  bthh_get_report_callback get_report_cb;
  bthh_virtual_unplug_callback virtual_unplug_cb;
  bthh_handshake_callback handshake_cb;

} bthh_callbacks_t;

/** Represents the standard BT-HH interface. */
typedef struct {
  /** set to sizeof(BtHhInterface) */
  size_t size;

  /**
   * Register the BtHh callbacks
   */
  bt_status_t (*init)(bthh_callbacks_t* callbacks);

  /** connect to hid device */
  bt_status_t (*connect)(RawAddress* bd_addr);

  /** dis-connect from hid device */
  bt_status_t (*disconnect)(RawAddress* bd_addr);

  /** Virtual UnPlug (VUP) the specified HID device */
  bt_status_t (*virtual_unplug)(RawAddress* bd_addr);

  /** Set the HID device descriptor for the specified HID device. */
  bt_status_t (*set_info)(RawAddress* bd_addr, bthh_hid_info_t hid_info);

  /** Get the HID proto mode. */
  bt_status_t (*get_protocol)(RawAddress* bd_addr,
                              bthh_protocol_mode_t protocolMode);

  /** Set the HID proto mode. */
  bt_status_t (*set_protocol)(RawAddress* bd_addr,
                              bthh_protocol_mode_t protocolMode);

  /** Get the HID Idle Time */
  bt_status_t (*get_idle_time)(RawAddress* bd_addr);

  /** Set the HID Idle Time */
  bt_status_t (*set_idle_time)(RawAddress* bd_addr, uint8_t idleTime);

  /** Send a GET_REPORT to HID device. */
  bt_status_t (*get_report)(RawAddress* bd_addr, bthh_report_type_t reportType,
                            uint8_t reportId, int bufferSize);

  /** Send a SET_REPORT to HID device. */
  bt_status_t (*set_report)(RawAddress* bd_addr, bthh_report_type_t reportType,
                            char* report);

  /** Send data to HID device. */
  bt_status_t (*send_data)(RawAddress* bd_addr, char* data);

  /** Closes the interface. */
  void (*cleanup)(void);

} bthh_interface_t;
__END_DECLS

#endif /* ANDROID_INCLUDE_BT_HH_H */
