[Adapt] Implement SSP and PIN request event handlers 63/78763/2
authorAnupam Roy <anupam.r@samsung.com>
Wed, 6 Jul 2016 19:15:04 +0000 (15:15 -0400)
committerPyun DoHyun <dh79.pyun@samsung.com>
Thu, 7 Jul 2016 01:48:23 +0000 (18:48 -0700)
This patch implements SSP and Legacy Pairing
handlers and send events to BT Frwk.

Change-Id: Id3710e9b51a74a6ba80d7dc7eb548a6df3d1ad15
Signed-off-by: Anupam Roy <anupam.r@samsung.com>
bt-service-adaptation/CMakeLists.txt
bt-service-adaptation/services/bt-service-agent-util.c [new file with mode: 0644]
bt-service-adaptation/services/bt-service-event-receiver.c
bt-service-adaptation/services/device/bt-service-core-device.c
bt-service-adaptation/services/include/bt-service-agent-util.h [new file with mode: 0644]
bt-service-adaptation/services/include/bt-service-core-device.h
bt-service-adaptation/services/include/stacktrim.h [new file with mode: 0755]

index 822a1be..c31a52a 100644 (file)
@@ -13,6 +13,7 @@ marshal.c
 ./services/device/bt-service-core-device.c
 ./services/bt-service-event-receiver.c
 ./services/bt-service-dpm.c
+./services/bt-service-agent-util.c
 )
 
 IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
diff --git a/bt-service-adaptation/services/bt-service-agent-util.c b/bt-service-adaptation/services/bt-service-agent-util.c
new file mode 100644 (file)
index 0000000..6d88e07
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ * Bluetooth-frwk
+ *
+ * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <malloc.h>
+#include <stacktrim.h>
+#include <syspopup_caller.h>
+
+#include "bt-internal-types.h"
+#include "bt-service-common.h"
+
+gboolean _bt_agent_is_hid_keyboard(unsigned int dev_class)
+{
+       switch ((dev_class & 0x1f00) >> 8) {
+               case 0x05:
+                       switch ((dev_class & 0xc0) >> 6) {
+                               case 0x01:
+                                       /* input-keyboard" */
+                                       return TRUE;
+                       }
+                       break;
+       }
+
+       return FALSE;
+}
+
+static gboolean __bt_agent_find_device_by_address_exactname(char *buffer,
+               const char *address)
+{
+       char *pch;
+       char *last;
+
+       pch = strtok_r(buffer, "= ,", &last);
+
+       if (pch == NULL)
+               return FALSE;
+
+       while ((pch = strtok_r(NULL, ",", &last))) {
+               if (0 == g_strcmp0(pch, address)) {
+                       BT_DBG("Match found\n");
+                       return TRUE;
+               }
+       }
+       return FALSE;
+}
+
+static gboolean __bt_agent_find_device_by_partial_name(char *buffer,
+               const char *partial_name)
+{
+       char *pch;
+       char *last;
+
+       pch = strtok_r(buffer, "= ,", &last);
+
+       if (pch == NULL)
+               return FALSE;
+
+       while ((pch = strtok_r(NULL, ",", &last))) {
+               if (g_str_has_prefix(partial_name, pch)) {
+                       BT_DBG("Match found\n");
+                       return TRUE;
+               }
+       }
+       return FALSE;
+}
+
+gboolean _bt_agent_is_device_blacklist(const char *address,
+               const char *name)
+{
+       char *buffer;
+       char **lines;
+       int i;
+       FILE *fp;
+       long size;
+       size_t result;
+
+       BT_DBG("+");
+
+       fp = fopen(BT_AGENT_AUTO_PAIR_BLACKLIST_FILE, "r");
+
+       if (fp == NULL) {
+               BT_ERR("Unable to open blacklist file");
+               return FALSE;
+       }
+
+       fseek(fp, 0, SEEK_END);
+       size = ftell(fp);
+       if (size <= 0) {
+               BT_DBG("size is not a positive number");
+               fclose(fp);
+               return FALSE;
+       }
+
+       rewind(fp);
+
+       buffer = g_malloc0(sizeof(char) * size);
+       /* Fix : NULL_RETURNS */
+       if (buffer == NULL) {
+               BT_ERR("Fail to allocate memory");
+               fclose(fp);
+               return FALSE;
+       }
+       result = fread((char *)buffer, 1, size, fp);
+       fclose(fp);
+       if (result != size) {
+               BT_ERR("Read Error");
+               g_free(buffer);
+               return FALSE;
+       }
+
+       BT_DBG("Buffer = %s", buffer);
+
+       lines = g_strsplit_set(buffer, BT_AGENT_NEW_LINE, 0);
+       g_free(buffer);
+
+       if (lines == NULL) {
+               BT_ERR("No lines in the file");
+               return FALSE;
+       }
+
+       for (i = 0; lines[i] != NULL; i++) {
+               if (g_str_has_prefix(lines[i], "AddressBlacklist"))
+                       if (__bt_agent_find_device_by_address_exactname(
+                                               lines[i], address))
+                               goto done;
+               if (g_str_has_prefix(lines[i], "ExactNameBlacklist"))
+                       if (__bt_agent_find_device_by_address_exactname(
+                                               lines[i], name))
+                               goto done;
+               if (g_str_has_prefix(lines[i], "PartialNameBlacklist"))
+                       if (__bt_agent_find_device_by_partial_name(lines[i],
+                                               name))
+                               goto done;
+               if (g_str_has_prefix(lines[i], "KeyboardAutoPair"))
+                       if (__bt_agent_find_device_by_address_exactname(
+                                               lines[i], address))
+                               goto done;
+       }
+       g_strfreev(lines);
+       BT_DBG("-");
+       return FALSE;
+done:
+       BT_DBG("Found the device");
+       g_strfreev(lines);
+       return TRUE;
+}
+
+void _bt_agent_release_memory(void)
+{
+       /* Release Malloc Memory*/
+       malloc_trim(0);
+
+       /* Release Stack Memory*/
+       stack_trim();
+}
+
+gboolean _bt_agent_is_auto_response(unsigned int dev_class,
+               const gchar *address, const gchar *name)
+{
+       gboolean is_headset = FALSE;
+       gboolean is_mouse = FALSE;
+       char lap_address[BT_LOWER_ADDRESS_LENGTH];
+
+       BT_DBG("bt_agent_is_headset_class, %d +", dev_class);
+
+       if (address == NULL)
+               return FALSE;
+
+       switch ((dev_class & 0x1f00) >> 8) {
+               case 0x04:
+                       switch ((dev_class & 0xfc) >> 2) {
+                               case 0x01:
+                               case 0x02:
+                                       /* Headset */
+                                       is_headset = TRUE;
+                                       break;
+                               case 0x06:
+                                       /* Headphone */
+                                       is_headset = TRUE;
+                                       break;
+                               case 0x0b:      /* VCR */
+                               case 0x0c:      /* Video Camera */
+                               case 0x0d:      /* Camcorder */
+                                       break;
+                               default:
+                                       /* Other audio device */
+                                       is_headset = TRUE;
+                                       break;
+                       }
+                       break;
+               case 0x05:
+                       switch (dev_class & 0xff) {
+                               case 0x80:  /* 0x80: Pointing device(Mouse) */
+                                       is_mouse = TRUE;
+                                       break;
+
+                               case 0x40: /* 0x40: input device (BT keyboard) */
+                                       /* Get the LAP(Lower Address part) */
+                                       g_strlcpy(lap_address, address, sizeof(lap_address));
+
+                                       /* Need to Auto pair the blacklisted Keyboard */
+                                       if (_bt_agent_is_device_blacklist(lap_address, name) != TRUE) {
+                                               BT_DBG("Device is not black listed\n");
+                                               return FALSE;
+                                       } else {
+                                               BT_ERR("Device is black listed\n");
+                                               return TRUE;
+                                       }
+                       }
+       }
+
+       if ((!is_headset) && (!is_mouse))
+               return FALSE;
+
+       /* Get the LAP(Lower Address part) */
+       g_strlcpy(lap_address, address, sizeof(lap_address));
+
+       BT_DBG("Device address = %s\n", address);
+       BT_DBG("Address 3 byte = %s\n", lap_address);
+
+       if (_bt_agent_is_device_blacklist(lap_address, name)) {
+               BT_ERR("Device is black listed\n");
+               return FALSE;
+       }
+       return TRUE;
+}
+
+int _bt_agent_generate_passkey(char *passkey, int size)
+{
+       int i;
+       ssize_t len;
+       int random_fd;
+       unsigned int value = 0;
+
+       if (passkey == NULL)
+               return -1;
+
+       if (size <= 0)
+               return -1;
+
+       random_fd = open("/dev/urandom", O_RDONLY);
+
+       if (random_fd < 0)
+               return -1;
+
+       for (i = 0; i < size; i++) {
+               len = read(random_fd, &value, sizeof(value));
+               if (len > 0)
+                       passkey[i] = '0' + (value % 10);
+       }
+       close(random_fd);
+       BT_DBG("passkey: %s", passkey);
+       return 0;
+}
index 94b2f65..7dd7318 100644 (file)
@@ -99,8 +99,14 @@ void _bt_service_oal_event_receiver(int event_type, gpointer event_data, gsize l
         case OAL_EVENT_DEVICE_BONDING_FAILED:
        case OAL_EVENT_DEVICE_ACL_CONNECTED:
         case OAL_EVENT_DEVICE_ACL_DISCONNECTED:
+       case OAL_EVENT_DEVICE_PIN_REQUEST:
+        case OAL_EVENT_DEVICE_PASSKEY_ENTRY_REQUEST:
+        case OAL_EVENT_DEVICE_PASSKEY_CONFIRMATION_REQUEST:
+        case OAL_EVENT_DEVICE_PASSKEY_DISPLAY:
+        case OAL_EVENT_DEVICE_SSP_CONSENT_REQUEST:
                 if (device_cb)
                         device_cb(event_type, event_data);
+               break;
        default:
                BT_ERR("Unhandled Event: %d", event_type);
                break;
index 38b4f0f..43b733a 100644 (file)
@@ -39,6 +39,7 @@
 #include "bt-service-event-receiver.h"
 #include "bt-request-handler.h"
 #include "bt-service-event.h"
+#include "bt-service-agent-util.h"
 
 /* OAL headers */
 #include <oal-event.h>
@@ -47,6 +48,7 @@
 #include <oal-device-mgr.h>
 
 #define MAX_BOND_RETRY_COUNT 3
+#define BT_PASSKEY_MAX_LENGTH 4
 
 /* Bonding Info structure */
 typedef struct {
@@ -60,10 +62,17 @@ typedef struct {
         bt_remote_dev_info_t *dev_info;
 } bt_bond_data_t;
 
+/* Pairing Info structure */
+typedef struct {
+        char *addr;
+        gboolean is_autopair;
+        int is_ssp;
+} bt_pairing_data_t;
 
 /* Bonding and Pairing Informations */
 bt_bond_data_t *trigger_bond_info;
 bt_bond_data_t *trigger_unbond_info;
+bt_pairing_data_t *trigger_pairing_info;
 
 typedef enum {
   BT_DEVICE_BOND_STATE_NONE,
@@ -98,6 +107,13 @@ static void __bt_device_handle_bond_failed_event(event_dev_bond_failed_t* bond_f
 static void __bt_handle_ongoing_bond(bt_remote_dev_info_t *remote_dev_info);
 static void __bt_device_acl_state_changed_callback(event_dev_conn_status_t * acl_event,
                                gboolean connected);
+static void __bt_free_pairing_info(bt_pairing_data_t **p_info);
+
+static void __bt_device_ssp_consent_callback(remote_device_t* dev_info);
+static void __bt_device_pin_request_callback(remote_device_t* pin_req_event);
+static void __bt_device_ssp_passkey_display_callback(event_dev_passkey_t *dev_info);
+static void __bt_device_ssp_passkey_confirmation_callback(event_dev_passkey_t *dev_info);
+static void __bt_device_ssp_passkey_entry_callback(remote_device_t* dev_info);
 
 void _bt_device_state_handle_callback_set_request(void)
 {
@@ -338,7 +354,7 @@ static void __bt_handle_ongoing_bond(bt_remote_dev_info_t *remote_dev_info)
                                BLUETOOTH_EVENT_BONDING_FINISHED,
                                param);
                __bt_free_bond_info(BT_DEVICE_BOND_INFO);
-               /* TODO Free pairing Info*/
+               __bt_free_pairing_info(&trigger_pairing_info);
        } else {
                BT_INFO("Lets wait for more remote device properties");
        }
@@ -396,7 +412,7 @@ static void __bt_device_handle_bond_removal_event(bt_address_t *bd_addr)
                                BLUETOOTH_EVENT_BONDED_DEVICE_REMOVED,
                                param);
                __bt_free_bond_info(BT_DEVICE_UNBOND_INFO);
-               /* TODO Free pairing info*/
+               __bt_free_pairing_info(&trigger_pairing_info);
        } else if (trigger_bond_info) {
                __bt_device_handle_bond_state();
        }
@@ -427,7 +443,7 @@ static void __bt_device_handle_bond_failed_event(event_dev_bond_failed_t* bond_f
                                __bt_device_handle_pending_requests(BLUETOOTH_ERROR_INTERNAL, BT_BOND_DEVICE,
                                                trigger_bond_info->addr, BT_ADDRESS_STRING_SIZE);
                                __bt_free_bond_info(BT_DEVICE_BOND_INFO);
-                       /* TODO Free pairing info */
+                               __bt_free_pairing_info(&trigger_pairing_info);
                                bond_retry_count = 0;
                        }
                }
@@ -448,7 +464,7 @@ static void __bt_device_handle_bond_failed_event(event_dev_bond_failed_t* bond_f
                        __bt_device_handle_pending_requests(result, BT_BOND_DEVICE,
                                        trigger_bond_info->addr, BT_ADDRESS_STRING_SIZE);
                        __bt_free_bond_info(BT_DEVICE_BOND_INFO);
-                       /* TODO Free pairing info */
+                       __bt_free_pairing_info(&trigger_pairing_info);
                }
                break;
        }
@@ -465,13 +481,13 @@ static void __bt_device_handle_bond_failed_event(event_dev_bond_failed_t* bond_f
                                        BLUETOOTH_EVENT_BONDED_DEVICE_REMOVED,
                                        param);
                        __bt_free_bond_info(BT_DEVICE_UNBOND_INFO);
-                       /* TODO Free pairing info */
+                       __bt_free_pairing_info(&trigger_pairing_info);
                } else if (trigger_bond_info) {
                        if (__bt_device_handle_bond_state()!= BLUETOOTH_ERROR_NONE) {
                                __bt_device_handle_pending_requests(BLUETOOTH_ERROR_INTERNAL, BT_BOND_DEVICE,
                                                trigger_bond_info->addr, BT_ADDRESS_STRING_SIZE);
                                __bt_free_bond_info(BT_DEVICE_BOND_INFO);
-                               /* TODO Free pairing info */
+                               __bt_free_pairing_info(&trigger_pairing_info);
                        }
                }
                break;
@@ -534,11 +550,259 @@ static void __bt_device_event_handler(int event_type, gpointer event_data)
                __bt_device_acl_state_changed_callback((event_dev_conn_status_t *)event_data, FALSE);
                break;
        }
+       case OAL_EVENT_DEVICE_PIN_REQUEST: {
+                  BT_INFO("PIN Request Received");
+                  __bt_device_pin_request_callback((remote_device_t*)event_data);
+                  break;
+       }
+       case OAL_EVENT_DEVICE_PASSKEY_ENTRY_REQUEST: {
+               BT_INFO("Passkey Entry request Received");
+               __bt_device_ssp_passkey_entry_callback((remote_device_t*)event_data);
+               break;
+       }
+       case OAL_EVENT_DEVICE_PASSKEY_CONFIRMATION_REQUEST:{
+                  BT_INFO("Passkey Confirmation Request Received");
+                  __bt_device_ssp_passkey_confirmation_callback((event_dev_passkey_t *)event_data);
+                  break;
+       }
+       case OAL_EVENT_DEVICE_PASSKEY_DISPLAY: {
+             BT_INFO("Passkey Display Request Received");
+             __bt_device_ssp_passkey_display_callback((event_dev_passkey_t *)event_data);
+             break;
+       }
+       case OAL_EVENT_DEVICE_SSP_CONSENT_REQUEST: {
+               BT_INFO("SSP Consent Request Received");
+                __bt_device_ssp_consent_callback((remote_device_t*)event_data);
+               break;
+       }
        default:
                BT_INFO("Unhandled event..");
        }
 }
 
+/* Legacy Pairing event handler */
+static void __bt_device_pin_request_callback(remote_device_t* pin_req_event)
+{
+       GVariant *param;
+       gchar address[BT_ADDRESS_STR_LEN];
+       BT_DBG("+");
+
+       _bt_convert_addr_type_to_string(address, pin_req_event->address.addr);
+
+       BT_INFO("Address[%s]", address);
+       BT_INFO("Name[%s]", pin_req_event->name);
+       BT_INFO("COD[%d]", pin_req_event->cod);
+
+       if (trigger_pairing_info) {
+               /* BTAPI support only one pairing at a time */
+               BT_ERR("Already Pairing address [%s]", trigger_pairing_info->addr);
+               BT_ERR("New PIN request address [%s]", address);
+               device_reject_pin_request(&pin_req_event->address);
+               return;
+       }
+
+       /* If user initiated bonding and auto response is possible, just reply with default 0000*/
+       if (_bt_is_bonding_device_address(address) == TRUE &&
+                       _bt_agent_is_auto_response(pin_req_event->cod, address, pin_req_event->name)) {
+               /* Note: Currently even if SYSPOPUP is supported, we use Fixed PIN "0000" for basic pairing
+                  as BT SYSPOPUP is currently not working for PIN KEY entry in Tizen platform. This needs
+                  to be checked and fixed apropriately */
+               _bt_set_autopair_status_in_bonding_info(TRUE);
+               device_accept_pin_request(&pin_req_event->address, "0000");
+       } else if (_bt_agent_is_hid_keyboard(pin_req_event->cod)) {
+               char str_passkey[BT_PASSKEY_MAX_LENGTH + 1] = { 0 };
+
+               if (_bt_agent_generate_passkey(str_passkey,
+                                       BT_PASSKEY_MAX_LENGTH) != 0) {
+                       device_reject_pin_request(&pin_req_event->address);
+                       goto done;
+               }
+               device_accept_pin_request(&pin_req_event->address, str_passkey);
+
+               BT_DBG("Send BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY");
+               param = g_variant_new("(isss)", BLUETOOTH_ERROR_NONE, address, pin_req_event->name, str_passkey);
+               _bt_send_event(BT_ADAPTER_EVENT,
+                               BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY, param);
+               BT_DBG("Key board pairing in process");
+       } else {
+               if (_bt_is_bonding_device_address(address) == TRUE) {
+                       BT_DBG("Show Pin entry");
+                       trigger_pairing_info = g_malloc0(sizeof(bt_pairing_data_t));
+                       trigger_pairing_info->addr = g_strdup(address);
+                       trigger_pairing_info->is_ssp = FALSE;
+
+                       BT_DBG("Send BLUETOOTH_EVENT_PIN_REQUEST");
+                       param = g_variant_new("(iss)", BLUETOOTH_ERROR_NONE, address, pin_req_event->name);
+                       _bt_send_event(BT_ADAPTER_EVENT,
+                                       BLUETOOTH_EVENT_PIN_REQUEST, param);
+               }
+       }
+
+done:
+       _bt_agent_release_memory();
+       BT_DBG("-");
+}
+
+
+static void __bt_device_ssp_passkey_entry_callback(remote_device_t* dev_info)
+{
+       GVariant *param;
+       gchar address[BT_ADDRESS_STR_LEN];
+       char *p_addr;
+       gchar *name;
+       int result = BLUETOOTH_ERROR_NONE;
+       BT_DBG("+");
+
+       _bt_convert_addr_type_to_string(address, dev_info->address.addr);
+       p_addr = address;
+       name = dev_info->name;
+
+       BT_INFO("Address[%s]", address);
+       BT_INFO("Name[%s]", name);
+       BT_INFO("COD[%d]", dev_info->cod);
+
+       if (trigger_pairing_info) {
+               /* BTAPI support only one pairing at a time */
+               BT_ERR("Already Pairing address [%s]", trigger_pairing_info->addr);
+               BT_ERR("New PIN request address [%s]", address);
+               device_reject_pin_request(&dev_info->address);
+               BT_DBG("-");
+               return;
+       }
+
+       /* Set pairing data */
+       trigger_pairing_info = g_malloc0(sizeof(bt_pairing_data_t));
+       trigger_pairing_info->addr = g_strdup(address);
+       trigger_pairing_info->is_ssp = TRUE;
+
+       param = g_variant_new("(iss)", result, p_addr, name);
+       _bt_send_event(BT_ADAPTER_EVENT,
+                       BLUETOOTH_EVENT_PASSKEY_REQUEST, param);
+       BT_DBG("-");
+}
+
+static void __bt_device_ssp_passkey_confirmation_callback(event_dev_passkey_t *dev_info)
+{
+       GVariant *param;
+       gchar address[BT_ADDRESS_STR_LEN];
+       char *p_addr;
+       gchar *name;
+       char str_passkey[7];
+       int result = BLUETOOTH_ERROR_NONE;
+       BT_DBG("+");
+
+       _bt_convert_addr_type_to_string(address, dev_info->device_info.address.addr);
+       p_addr = address;
+       name = dev_info->device_info.name;
+
+       BT_INFO("Address[%s]", address);
+       BT_INFO("Name[%s]", name);
+       BT_INFO("COD[%d]", dev_info->device_info.cod);
+
+       if (trigger_pairing_info) {
+               /* BTAPI support only one pairing at a time */
+               BT_ERR("Already Pairing address [%s]", trigger_pairing_info->addr);
+               BT_ERR("New PIN request address [%s]", address);
+               device_reject_pin_request(&dev_info->device_info.address);
+               BT_DBG("-");
+               return;
+       }
+
+       /* Set pairing data */
+       trigger_pairing_info = g_malloc0(sizeof(bt_pairing_data_t));
+       trigger_pairing_info->addr = g_strdup(address);
+       trigger_pairing_info->is_ssp = TRUE;
+
+       BT_DBG("Send BLUETOOTH_EVENT_PASSKEY_CONFIRMATION");
+       snprintf(str_passkey, sizeof(str_passkey), "%.6d", dev_info->pass_key);
+
+       param = g_variant_new("(isss)", result, p_addr, name, str_passkey);
+       _bt_send_event(BT_ADAPTER_EVENT,
+                       BLUETOOTH_EVENT_PASSKEY_CONFIRM_REQUEST, param);
+       BT_DBG("-");
+}
+
+static void __bt_device_ssp_passkey_display_callback(event_dev_passkey_t *dev_info)
+{
+       GVariant *param;
+       gchar address[BT_ADDRESS_STR_LEN];
+       char *p_addr;
+       gchar *name;
+       char str_passkey[7];
+       int result = BLUETOOTH_ERROR_NONE;
+       BT_DBG("+");
+
+       _bt_convert_addr_type_to_string(address, dev_info->device_info.address.addr);
+       p_addr = address;
+       name = dev_info->device_info.name;
+
+       BT_INFO("Address[%s]", address);
+       BT_INFO("Name[%s]", name);
+       BT_INFO("COD[%d]", dev_info->device_info.cod);
+
+       if (trigger_pairing_info) {
+               /* BTAPI support only one pairing at a time */
+               BT_ERR("Already Pairing address [%s]", trigger_pairing_info->addr);
+               BT_ERR("New PIN request address [%s]", address);
+               device_reject_pin_request(&dev_info->device_info.address);
+               BT_DBG("-");
+               return;
+       }
+
+       /* Set pairing data */
+       trigger_pairing_info = g_malloc0(sizeof(bt_pairing_data_t));
+       trigger_pairing_info->addr = g_strdup(address);
+       trigger_pairing_info->is_ssp = TRUE;
+
+       BT_DBG("Send BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY");
+       snprintf(str_passkey, sizeof(str_passkey), "%.6d", dev_info->pass_key);
+
+       param = g_variant_new("(isss)", result, p_addr, name, str_passkey);
+       _bt_send_event(BT_ADAPTER_EVENT,
+                       BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY, param);
+       BT_DBG("-");
+
+}
+
+static void __bt_device_ssp_consent_callback(remote_device_t* dev_info)
+{
+       gchar address[BT_ADDRESS_STR_LEN];
+       gchar *name;
+       int local_major;
+       int local_minor;
+       int cod;
+       BT_DBG("+");
+
+       _bt_convert_addr_type_to_string(address, dev_info->address.addr);
+       name = dev_info->name;
+       cod = dev_info->cod;
+
+       BT_INFO("Address[%s]", address);
+       BT_INFO("Name[%s]", name);
+       BT_INFO("COD[%d]", cod);
+
+       if (trigger_pairing_info) {
+               /* BTAPI support only one pairing at a time */
+               BT_ERR("Already Pairing address [%s]", trigger_pairing_info->addr);
+               BT_ERR("New PIN request address [%s]", address);
+               device_reject_pin_request(&dev_info->address);
+               BT_DBG("-");
+               return;
+       }
+
+       /* Set pairing data */
+       trigger_pairing_info = g_malloc0(sizeof(bt_pairing_data_t));
+       trigger_pairing_info->addr = g_strdup(address);
+       trigger_pairing_info->is_ssp = TRUE;
+
+       local_major = ((cod >> 8) & 0x001f);
+       local_minor = (cod & 0x00fc);
+       BT_DBG("SSP_CONSENT: Major type=[0x%x] and Minor type=[0x%x]",local_major, local_minor);
+
+       /*TODO: BLUETOOTH_EVENT_SSP_CONSENT_REQUEST to be handled in Tizen */
+       BT_DBG("-");
+}
+
 static void __bt_device_acl_state_changed_callback(event_dev_conn_status_t * acl_event, gboolean connected)
 {
        gchar address[BT_ADDRESS_STR_LEN];
@@ -635,6 +899,19 @@ static void __bt_device_remote_device_found_callback(gpointer event_data, gboole
        BT_DBG("-");
 }
 
+static void __bt_free_pairing_info(bt_pairing_data_t **p_info)
+{
+       bt_pairing_data_t * info = *p_info;
+       if (info) {
+               if(info->addr) {
+                       g_free(info->addr);
+               }
+
+               g_free(info);
+       }
+       *p_info = NULL;
+}
+
 static void __bt_free_bond_info(uint8_t type)
 {
        BT_INFO("+");
@@ -709,7 +986,7 @@ static int __bt_device_handle_bond_state(void)
                        __bt_device_handle_pending_requests(BLUETOOTH_ERROR_INTERNAL, BT_BOND_DEVICE,
                                        trigger_bond_info->addr, BT_ADDRESS_STRING_SIZE);
                        __bt_free_bond_info(BT_DEVICE_BOND_INFO);
-                       /* TODO: Free pairing Info */
+                       __bt_free_pairing_info(&trigger_pairing_info);
                }
                break;
        case BT_DEVICE_BOND_STATE_NONE:
@@ -862,3 +1139,33 @@ fail:
 
        return result;
 }
+
+gboolean _bt_device_is_pairing(void)
+{
+        return (trigger_pairing_info) ? TRUE : FALSE;
+}
+
+gboolean _bt_device_is_bonding(void)
+{
+        return (trigger_bond_info) ? TRUE : FALSE;
+}
+
+gboolean _bt_is_bonding_device_address(const char *address)
+{
+       if (trigger_bond_info == NULL || trigger_bond_info->addr == NULL)
+               return FALSE;
+
+       if (g_strcmp0(trigger_bond_info->addr, address) == 0) {
+               BT_DBG("[%s]  is bonding device", address);
+               return TRUE;
+       }
+
+       BT_DBG("[%s]  is NOT bonding device", address);
+       return FALSE;
+}
+
+void _bt_set_autopair_status_in_bonding_info(gboolean is_autopair)
+{
+        ret_if (trigger_bond_info == NULL);
+        trigger_bond_info->is_autopair = is_autopair;
+}
diff --git a/bt-service-adaptation/services/include/bt-service-agent-util.h b/bt-service-adaptation/services/include/bt-service-agent-util.h
new file mode 100644 (file)
index 0000000..eee263c
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Bluetooth-frwk
+ *
+ * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 _BT_SERVICE_AGENT_UTIL_H_
+#define _BT_SERVICE_AGENT_UTIL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+gboolean _bt_agent_is_auto_response(unsigned int dev_class,
+                                const gchar *address, const gchar *name);
+
+int _bt_agent_generate_passkey(char *passkey, int size);
+
+gboolean _bt_agent_is_device_blacklist(const char *address,
+                                                        const char *name);
+
+void _bt_agent_release_memory(void);
+
+gboolean _bt_agent_is_hid_keyboard(unsigned int dev_class);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /*_BT_SERVICE_AGENT_UTIL_H_*/
index f981899..2cc360b 100755 (executable)
@@ -38,6 +38,16 @@ int _bt_bond_device(bluetooth_device_address_t *device_address,
 int _bt_unbond_device(bluetooth_device_address_t *device_address,
                         GArray **out_param1);
 
+gboolean _bt_is_bonding_device_address(const char *address);
+
+gboolean _bt_device_is_bonding(void);
+
+gboolean _bt_device_is_pairing(void);
+
+gboolean _bt_is_bonding_device_address(const char *address);
+
+void _bt_set_autopair_status_in_bonding_info(gboolean is_autopair);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/bt-service-adaptation/services/include/stacktrim.h b/bt-service-adaptation/services/include/stacktrim.h
new file mode 100755 (executable)
index 0000000..df92523
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 __STACKTRIM_H__
+#define __STACKTRIM_H__
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/mman.h>
+
+#define BUF_SIZE               256
+#define PAGE_SIZE              (1 << 12)
+#define _ALIGN_UP(addr, size)    (((addr)+((size)-1))&(~((size)-1)))
+#define _ALIGN_DOWN(addr, size)        ((addr)&(~((size)-1)))
+#define PAGE_ALIGN(addr)        _ALIGN_DOWN(addr, PAGE_SIZE)
+
+static inline void stack_trim(void)
+{
+#ifdef STACK_FLUSH
+       unsigned int sp;
+       char buf[BUF_SIZE];
+       FILE *file;
+       unsigned int stacktop;
+       int found = 0;
+
+       asm volatile ("mov %0,sp " : "=r"(sp));
+
+       sprintf(buf, "/proc/%d/maps", getpid());
+       file = fopen(buf, "r");
+       while (fgets(buf, BUF_SIZE, file) != NULL) {
+               if (strstr(buf, "[stack]")) {
+                       found = 1;
+                       break;
+               }
+       }
+       fclose(file);
+
+       if (found) {
+               sscanf(buf, "%x-", &stacktop);
+               if (madvise((void *)PAGE_ALIGN(stacktop), PAGE_ALIGN(sp) - stacktop,
+                                                                               MADV_DONTNEED) < 0)
+                       perror("stack madvise fail");
+       }
+#endif
+}
+
+#endif                         /* __STACKTRIM_H__ */