[Adapt: OAL] Added HID host APIs and Callbacks 61/78861/2
authorAtul Rai <a.rai@samsung.com>
Thu, 7 Jul 2016 07:34:49 +0000 (16:34 +0900)
committerPyun DoHyun <dh79.pyun@samsung.com>
Mon, 11 Jul 2016 08:12:08 +0000 (01:12 -0700)
This patch adds HID Host profile APIs, Callbacks and Events
implementation in OAL.

Change-Id: If7f55d38fa1d04b7066a4c4d10b2afae3ba3977a
Signed-off-by: Atul Rai <a.rai@samsung.com>
bt-oal/CMakeLists.txt
bt-oal/include/oal-event.h
bt-oal/include/oal-hid-host.h [new file with mode: 0755]
bt-oal/oal-hid-host.c [new file with mode: 0755]
bt-oal/oal-internal.h

index be80e83..520b0bc 100755 (executable)
@@ -14,6 +14,7 @@ oal-hardware.c
 oal-manager.c
 oal-adapter-mgr.c
 oal-device-mgr.c
+oal-hid-host.c
 common/oal-utils.c
 common/oal-common.c
 common/oal-event-dispatcher.c
index e73a760..fdc4d7d 100755 (executable)
@@ -65,6 +65,8 @@ extern "C" {
        EVENT(OAL_EVENT_DEVICE_ACL_DISCONNECTED)                        /* bt_address_t */\
        EVENT(OAL_EVENT_OAL_INITIALISED_SUCCESS)                /* OAL Initialisation event */  \
        EVENT(OAL_EVENT_OAL_INITIALISED_FAILED)                 /* OAL Initialisation event */  \
+       EVENT(OAL_EVENT_HID_CONNECTED)                                          /* event_hid_conn_t */\
+       EVENT(OAL_EVENT_HID_DISCONNECTED)                                       /* event_hid_conn_t */\
        EVENT(OAL_EVENT_END)                                /* End of event*/\
 
 
@@ -134,6 +136,13 @@ typedef struct {
 
 typedef event_dev_conn_status_t event_dev_bond_failed_t;
 
+/*********Datastructures for HID callback******************/
+/* HID :: connection state callback response data */
+typedef struct {
+       bt_address_t address;
+       oal_status_t status;
+} event_hid_conn_t;
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/bt-oal/include/oal-hid-host.h b/bt-oal/include/oal-hid-host.h
new file mode 100755 (executable)
index 0000000..e8be071
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Open Adaptation Layer (OAL)
+ *
+ * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd.
+ *
+ * Contact: Anupam Roy <anupam.r@samsung.com>
+ *
+ * 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 _OAL_HID_HOST_H_
+#define _OAL_HID_HOST_H_
+
+#include <glib.h>
+#include <sys/types.h>
+
+#include <oal-manager.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define OAL_SMART_RC_FEATURE_REPORT_ID 0x03
+
+/**
+ * @brief HID Vendor specific report callback
+*/
+typedef void (*hid_report_callback)(bt_address_t *address, uint8_t* rpt_data, int rpt_size);
+
+/**
+ * @brief Enable HID Host Feature
+ *
+ * @remarks  HID mouse/keyboard/RC will be able to connect.
+ *
+ * @return OAL_STATUS_SUCCESS on success, otherwise non-zero error value.
+ * @retval #OAL_STATUS_SUCCESS Successful
+ *
+ * @pre OAL API must be initialized with oal_bt_init().
+ *
+ * @see  hid_disable()
+ */
+oal_status_t hid_enable(void);
+
+
+/**
+ * @brief Disable HID Host Feature
+ *
+ * @remarks  HID mouse/keyboard/RC will not be able to connect.
+ *
+ * @return OAL_STATUS_SUCCESS on success, otherwise a non-zero error value.
+ * @retval #OAL_STATUS_SUCCESS Successful
+ *
+ * @pre HID host should be enabled with hid_enable().
+ *
+ * @see  hid_enable()
+ */
+oal_status_t hid_disable(void);
+
+/**
+ * @brief Initiate connection with an HID device
+ *
+ * @details  Result will be notified through an OAL event
+ *
+ * @return OAL_STATUS_SUCCESS on success, otherwise a non-zero error value.
+ * @retval #OAL_STATUS_SUCCESS Successful
+ *
+ * @pre HID host should be enabled with hid_enable().
+ *
+ * @see  OAL_EVENT_HID_CONNECTED
+ */
+oal_status_t hid_connect(bt_address_t *address);
+
+/**
+ * @brief Remove a connection with an HID device
+ *
+ * @details  Result will be notified through an OAL event
+ *
+ * @return OAL_STATUS_SUCCESS on success, otherwise a non-zero error value.
+ * @retval #OAL_STATUS_SUCCESS Successful
+ *
+ * @pre HID host should be connected with a device.
+ *
+ * @see  OAL_EVENT_HID_DISCONNECTED
+ */
+oal_status_t hid_disconnect(bt_address_t * address);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* _OAL_HID_HOST_H_ */
diff --git a/bt-oal/oal-hid-host.c b/bt-oal/oal-hid-host.c
new file mode 100755 (executable)
index 0000000..bbc5757
--- /dev/null
@@ -0,0 +1,261 @@
+/*
+ * Open Adaptation Layer (OAL)
+ *
+ * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ *
+ */
+
+#include <stdio.h>
+#include <dlog.h>
+#include <string.h>
+
+#include <bluetooth.h>
+#include <bt_hh.h>
+
+#include "oal-event.h"
+#include "oal-internal.h"
+#include "oal-common.h"
+#include "oal-manager.h"
+#include "oal-hid-host.h"
+#include "oal-utils.h"
+
+#define CHECK_OAL_HID_ENABLED() \
+       do { \
+               if (hid_api == NULL) { \
+                       BT_ERR("HID Not Enabled"); \
+                       return OAL_STATUS_NOT_READY; \
+               } \
+       } while (0)
+
+static void connection_state_callback(bt_bdaddr_t *bd_addr, bthh_connection_state_t state);
+static void hid_info_callback(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info);
+static void get_protocol_mode_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, bthh_protocol_mode_t mode);
+static void idle_time_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, int idle_rate);
+static void get_report_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, uint8_t* rpt_data, int rpt_size);
+static void virtual_unplug_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status);
+static void handshake_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status);
+
+static const bthh_interface_t * hid_api;
+
+static bthh_callbacks_t sBluetoothHidCallbacks = {
+       sizeof(sBluetoothHidCallbacks),
+       connection_state_callback,
+       hid_info_callback,
+       get_protocol_mode_callback,
+       idle_time_callback,
+       get_report_callback,
+       virtual_unplug_callback,
+       handshake_callback,
+};
+
+oal_status_t hid_enable(void)
+{
+       const bt_interface_t * blued_api;
+       int ret;
+
+       API_TRACE();
+       blued_api = adapter_get_stack_interface();
+
+       if(blued_api == NULL) {
+               BT_ERR("Stack is not initialized");
+               return OAL_STATUS_NOT_READY;
+       }
+       if(hid_api != NULL){
+               BT_WARN("HID Interface is already initialized...");
+               return OAL_STATUS_ALREADY_DONE;
+       }
+
+       hid_api = (const bthh_interface_t *)blued_api->get_profile_interface(BT_PROFILE_HIDHOST_ID);
+
+       if(hid_api == NULL) {
+               BT_ERR("HID interface failed");
+               return OAL_STATUS_INTERNAL_ERROR;
+       }
+
+       if((ret = hid_api->init(&sBluetoothHidCallbacks)) != BT_STATUS_SUCCESS) {
+               BT_ERR("HID Init failed: %s", status2string(ret));
+               hid_api->cleanup();
+               hid_api = NULL;
+               return convert_to_oal_status(ret);
+       }
+       return OAL_STATUS_SUCCESS;
+}
+
+oal_status_t hid_disable(void)
+{
+       API_TRACE();
+
+       CHECK_OAL_HID_ENABLED();
+
+       hid_api->cleanup();
+
+       hid_api = NULL;
+       return OAL_STATUS_SUCCESS;
+}
+
+void hid_cleanup(void)
+{
+       BT_DBG();
+       hid_api = NULL;
+}
+
+oal_status_t hid_connect(bt_address_t * address)
+{
+       int ret;
+       bdstr_t bdstr;
+
+       API_TRACE();
+       CHECK_OAL_HID_ENABLED();
+       BT_INFO("[%s]", bdt_bd2str(address, &bdstr));
+
+       ret = hid_api->connect((bt_bdaddr_t*)address);
+       if(ret != BT_STATUS_SUCCESS) {
+               BT_ERR("ret: %s", status2string(ret));
+               return convert_to_oal_status(ret);
+       }
+       return OAL_STATUS_SUCCESS;
+}
+
+oal_status_t hid_disconnect(bt_address_t * address)
+{
+       int ret;
+       bdstr_t bdstr;
+
+       API_TRACE();
+       CHECK_OAL_HID_ENABLED();
+
+       BT_INFO("[%s]", bdt_bd2str(address, &bdstr));
+
+       ret = hid_api->disconnect((bt_bdaddr_t*)address);
+       if(ret != BT_STATUS_SUCCESS) {
+               BT_ERR("ret: %s", status2string(ret));
+               return convert_to_oal_status(ret);
+       }
+       return OAL_STATUS_SUCCESS;
+}
+
+oal_status_t hid_set_report(bt_address_t *address,
+               bthh_report_type_t reportType, char *report)
+{
+       int ret;
+       bdstr_t bdstr;
+
+       API_TRACE("len: %d", strlen(report));
+       CHECK_OAL_HID_ENABLED();
+       OAL_CHECK_PARAMETER(address, return);
+       OAL_CHECK_PARAMETER(report, return);
+       BT_INFO("[%s]", bdt_bd2str(address, &bdstr));
+       BT_INFO("[data:%s]", report);
+
+       ret = hid_api->set_report((bt_bdaddr_t*)address, reportType, report);
+       if(ret != BT_STATUS_SUCCESS) {
+               BT_ERR("ret: %s", status2string(ret));
+               return convert_to_oal_status(ret);
+       }
+       return OAL_STATUS_SUCCESS;
+}
+
+oal_status_t hid_send_data(bt_address_t *address, uint8_t *buf, uint16_t len)
+{
+       int ret;
+       bdstr_t bdstr;
+
+       API_TRACE("len: %d", len);
+       CHECK_OAL_HID_ENABLED();
+       OAL_CHECK_PARAMETER(address, return);
+       OAL_CHECK_PARAMETER(buf, return);
+
+       BT_INFO("[%s]", bdt_bd2str(address, &bdstr));
+
+       ret = hid_api->send_data((bt_bdaddr_t*)address, (char *)buf);
+       if(ret != BT_STATUS_SUCCESS) {
+               BT_ERR("ret: %s", status2string(ret));
+               return convert_to_oal_status(ret);
+       }
+       return OAL_STATUS_SUCCESS;
+}
+
+static void connection_state_callback(bt_bdaddr_t *bd_addr, bthh_connection_state_t state)
+{
+       event_hid_conn_t *event = g_new0(event_hid_conn_t, 1);
+       int event_type;
+
+       BT_DBG("%d", state);
+
+       memcpy(event->address.addr, bd_addr->address, BT_ADDRESS_BYTES_NUM);
+
+       event->status = OAL_STATUS_SUCCESS;
+
+       switch(state) {
+       case BTHH_CONN_STATE_CONNECTED:
+               event_type = OAL_EVENT_HID_CONNECTED;
+               break;
+       case BTHH_CONN_STATE_DISCONNECTED:
+               event_type = OAL_EVENT_HID_DISCONNECTED;
+               break;
+       case BTHH_CONN_STATE_CONNECTING:
+       case BTHH_CONN_STATE_DISCONNECTING:
+               return;
+       case BTHH_CONN_STATE_FAILED_MOUSE_FROM_HOST:
+               event_type = OAL_EVENT_HID_DISCONNECTED;
+               event->status = OAL_STATUS_HID_FAILED_MOUSE;
+               break;
+       case BTHH_CONN_STATE_FAILED_KBD_FROM_HOST:
+       case BTHH_CONN_STATE_FAILED_TOO_MANY_DEVICES:
+       case BTHH_CONN_STATE_FAILED_NO_BTHID_DRIVER:
+       case BTHH_CONN_STATE_FAILED_GENERIC:
+               BT_ERR("HID Connection SPECIAL state(%d)", state);
+               event_type = OAL_EVENT_HID_DISCONNECTED;
+               event->status = OAL_STATUS_INTERNAL_ERROR;
+               break;
+       case BTHH_CONN_STATE_UNKNOWN:
+       default:
+               BT_ERR("Unhandled Connection state %d", state);
+               return;
+       }
+
+       send_event_bda_trace(event_type, event, sizeof (event_hid_conn_t), (bt_address_t*)bd_addr);
+}
+
+static void hid_info_callback(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info)
+{
+       BT_INFO("");
+}
+
+static void get_protocol_mode_callback(bt_bdaddr_t *bd_addr,
+               bthh_status_t hh_status,bthh_protocol_mode_t mode)
+{
+       BT_INFO("status: %d, mode: %d", hh_status, mode);
+}
+
+static void idle_time_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, int idle_rate)
+{
+       BT_INFO("status: %d", hh_status);
+}
+
+static void get_report_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, uint8_t* rpt_data, int rpt_size)
+{
+       BT_INFO("status: %d", hh_status);
+}
+
+static void virtual_unplug_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status)
+{
+       BT_INFO("status: %d", hh_status);
+}
+
+static void handshake_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status)
+{
+       BT_INFO("status: %d", hh_status);
+}
index eeb820b..ba612e1 100755 (executable)
@@ -120,6 +120,7 @@ void device_mgr_init(const bt_interface_t * stack_if);
 void device_mgr_cleanup(void);
 
 oal_status_t adapter_mgr_init(const bt_interface_t * stack_if);
+const bt_interface_t* adapter_get_stack_interface(void);
 
 /* Event Manager */
 /* Use this when Address is to be printed */