4 * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Anupam Roy <anupam.r@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
29 #include <bundle_internal.h>
30 #include <eventsystem.h>
44 #include "bt-hal-log.h"
45 #include "bt-hal-msg.h"
46 #include "bt-hal-internal.h"
47 #include "bt-hal-utils.h"
48 #include "bt-hal-event-receiver.h"
49 #include "bt-hal-dbus-common-utils.h"
51 #include "bt-hal-adapter-dbus-handler.h"
52 #include "bt-hal-rfcomm-dbus-handler.h"
53 #include "bt-hal-event-receiver.h"
55 #include <bt-hal-agent.h>
56 #include <bt-hal-gap-agent.h>
57 #include <bt-hal-dbus-common-utils.h>
59 /* TODO_40 : 4.0 merge */
60 #include "bt-internal-types.h"
62 #define BT_HAL_AGENT_AUTO_PAIR_BLACKLIST_FILE (APP_SYSCONFDIR"/auto-pair-blacklist")
63 #define BT_HAL_AGENT_NEW_LINE "\r\n"
65 #define PAGE_SIZE (1 << 12)
66 #define _ALIGN_UP(addr, size) (((addr)+((size)-1))&(~((size)-1)))
67 #define _ALIGN_DOWN(addr, size) ((addr)&(~((size)-1)))
68 #define PAGE_ALIGN(addr) _ALIGN_DOWN(addr, PAGE_SIZE)
69 #define BT_HAL_PIN_MAX_LENGTH 16
70 #define BT_HAL_PASSKEY_MAX_LENGTH 4
71 #define BT_HAL_LOWER_ADDRESS_LENGTH 9
72 #define BT_HAL_AGENT_SYSPOPUP_TIMEOUT_FOR_MULTIPLE_POPUPS 200
73 #define BT_HAL_AGENT_SYSPOPUP_MAX_ATTEMPT 3
75 #define G_VARIANT_UNREF(variant) \
76 g_variant_unref(variant); \
78 #define BT_HAL_MAX_EVENT_STR_LENGTH 50
80 static void *adapter_agent = NULL;
81 static gboolean passkey_display_notification = FALSE;
82 static gboolean passkey_confirm_notification = FALSE;
83 static gboolean passkey_notification = FALSE;
84 static gboolean pincode_notification = FALSE;
86 /* Forward delcaration */
87 static void __bt_hal_send_pin_request_event(const gchar *address, const gchar *name,
89 static gboolean __bt_hal_pincode_request(GapAgentPrivate *agent, GDBusProxy *device);
90 static gboolean __bt_hal_display_request(GapAgentPrivate *agent, GDBusProxy *device,
92 static gboolean __bt_hal_passkey_request(GapAgentPrivate *agent, GDBusProxy *device);
93 static gboolean __bt_hal_confirm_request(GapAgentPrivate *agent, GDBusProxy *device,
95 static gboolean __bt_hal_authorize_request(GapAgentPrivate *agent, GDBusProxy *device,
97 static gboolean __bt_hal_authorize_cancel_request(GapAgentPrivate *agent, const char *address);
98 static gboolean __bt_hal_pairing_cancel_request(GapAgentPrivate *agent, const char *address);
99 static GVariant *__bt_hal_service_getall(GDBusProxy *device, const char *interface);
100 static void __bt_hal_agent_release_memory(void);
101 static inline void stack_trim(void);
103 static gboolean __bt_hal_device_is_hid_keyboard(unsigned int dev_class);
104 static int __bt_hal_device_generate_passkey(char *passkey, int size);
105 static gboolean __bt_hal_device_is_auto_response(uint32_t dev_class,
106 const gchar *address, const gchar *name);
107 static gboolean __bt_hal_device_is_device_blacklisted(const char *address, const char *name);
108 static gboolean __bt_hal_find_device_by_address_exactname(char *buffer,
109 const char *address);
110 static gboolean __bt_hal_find_device_by_partial_name(char *buffer,
111 const char *partial_name);
112 static void __bt_hal_send_ssp_request_events(const gchar *address, const gchar *name,
113 guint passkey, uint32_t cod, unsigned char variant);
114 static void __bt_hal_send_authorize_request_event(const gchar *address, const char *uuid);
116 void* _bt_hal_create_agent(const char *path, gboolean adapter)
118 GAP_AGENT_FUNC_CB func_cb;
119 GDBusProxy *adapter_proxy;
120 GapAgentPrivate *agent;
123 adapter_proxy = _bt_hal_get_adapter_proxy();
127 func_cb.pincode_func = __bt_hal_pincode_request;
128 func_cb.display_func = __bt_hal_display_request;
129 func_cb.passkey_func = __bt_hal_passkey_request;
130 func_cb.confirm_func = __bt_hal_confirm_request;
131 func_cb.authorize_func = __bt_hal_authorize_request;
132 func_cb.pairing_cancel_func = __bt_hal_pairing_cancel_request;
133 func_cb.authorization_cancel_func = __bt_hal_authorize_cancel_request;
136 agent = g_new0(GapAgentPrivate, 1);
138 _gap_agent_setup_dbus(agent, &func_cb, path, adapter_proxy);
141 if (!_gap_agent_register(agent)) {
142 ERR("gap agent registration failed!");
143 _bt_hal_destroy_agent(agent);
151 void _bt_hal_destroy_agent(void *agent)
157 _gap_agent_reset_dbus((GapAgentPrivate *)agent);
163 gboolean _bt_hal_agent_is_canceled(void)
165 void *agent = _bt_hal_get_adapter_agent();
169 return _gap_agent_is_canceled(agent);
172 int _bt_hal_agent_reply_cancellation(void)
174 void *agent = _bt_hal_get_adapter_agent();
176 return BT_STATUS_FAIL;
178 if (gap_agent_reply_confirmation(agent, GAP_AGENT_CANCEL, NULL) != TRUE) {
179 ERR("Fail to reply agent");
180 return BT_STATUS_FAIL;
182 DBG("gap agent cancellation done successfully!");
183 return BT_STATUS_SUCCESS;
187 void _bt_hal_agent_set_canceled(gboolean value)
189 void *agent = _bt_hal_get_adapter_agent();
193 return _gap_agent_set_canceled(agent, value);
196 void _bt_hal_initialize_adapter_agent(void)
198 adapter_agent = _bt_hal_create_agent(BT_HAL_ADAPTER_AGENT_PATH, TRUE);
199 if (!adapter_agent) {
200 ERR("Fail to register agent");
205 void _bt_hal_destroy_adapter_agent(void)
208 _bt_hal_destroy_agent(adapter_agent);
209 adapter_agent = NULL;
212 void* _bt_hal_get_adapter_agent(void)
214 return adapter_agent;
217 void _bt_hal_enable_gap_auth_notifications(unsigned int type, gboolean enable)
219 INFO("type: %d, enable: %d", type, enable);
222 case BT_PASSKEY_CONFIRMATION:
223 /* Note: Currently not used for notification sending, should be used when required */
224 passkey_confirm_notification = enable;
226 case BT_PASSKEY_DISPLAY:
227 passkey_display_notification = enable;
229 case BT_PASSKEY_ENTRY:
230 /* Note: Currently not used for notification sending, should be used when required */
231 passkey_notification = enable;
233 case BT_PINCODE_ENTRY:
234 pincode_notification = enable;
237 ERR("Unknown type: %d", type);
241 static void __bt_hal_send_authorize_request_event(const gchar *address, const char *uuid)
243 struct hal_ev_authorize_request ev;
244 memset(&ev, 0, sizeof(ev));
246 DBG("Remote Device address [%s]", address);
248 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
250 /* UUID received in authorization request (In case of HFP unit, UUID received from Bluez
251 would be of that of Audio Gateway UUID (0x111f) */
252 ev.service_id = _bt_convert_uuid_string_to_service_id(uuid);
254 handle_stack_msg event_cb = _bt_hal_get_stack_message_handler();
256 DBG("Sending AUTHORIZE REQUEST");
257 event_cb(HAL_EV_AUTHORIZE_REQUEST, (void*)&ev, sizeof(ev));
264 static void __bt_hal_send_rfcomm_authorize_request_event(const gchar *address, const char *uuid)
266 struct hal_ev_sock_conn_auth ev;
268 DBG("Remote Device address [%s], uuid: %s", address, uuid);
270 memset(&ev, 0, sizeof(ev));
271 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
272 _bt_hal_convert_uuid_string_to_type(ev.uuid, uuid);
274 handle_stack_msg event_cb = _bt_hal_get_stack_message_handler();
276 DBG("Sending Socket AUTHORIZE REQUEST");
277 event_cb(HAL_EV_SOCK_AUTHORIZE_REQUEST, (void*)&ev, sizeof(ev));
285 static void __bt_hal_send_pin_request_event(const gchar *address, const gchar *name,
288 struct hal_ev_pin_request ev;
289 memset(&ev, 0, sizeof(ev));
291 DBG("Remote Device address [%s]", address);
292 DBG("Remote Device Name [%s]", name);
293 DBG("Remote Device COD [%u]", cod);
295 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
297 memcpy(ev.name, name, strlen(name)+1);
298 ev.class_of_dev = cod;
300 handle_stack_msg event_cb = _bt_hal_get_stack_message_handler();
302 DBG("Sending PIN REQUEST");
303 event_cb(HAL_EV_PIN_REQUEST, (void*)&ev, sizeof(ev));
310 void __bt_hal_get_auth_info(GVariant *reply, char *auth_info)
314 char *manufacturer_data = NULL;
315 int manufacturer_data_len;
316 gboolean is_alias_set;
317 GVariantIter *value_iter;
321 tmp_value = g_variant_lookup_value(reply, "IsAliasSet",
322 G_VARIANT_TYPE_BOOLEAN);
324 is_alias_set = g_variant_get_boolean(tmp_value);
325 g_variant_unref(tmp_value);
327 is_alias_set = FALSE;
329 if (is_alias_set == FALSE) {
330 tmp_value = g_variant_lookup_value(reply, "LagacyManufacturerDataLen",
331 G_VARIANT_TYPE_UINT16);
333 manufacturer_data_len = g_variant_get_uint16(tmp_value);
334 if (manufacturer_data_len >
335 MAX_MANUFACTURE_LEN) {
336 ERR("manufacturer_data_len is too long");
337 manufacturer_data_len = MAX_MANUFACTURE_LEN;
339 g_variant_unref(tmp_value);
341 manufacturer_data_len = 0;
343 tmp_value = g_variant_lookup_value(reply, "LagacyManufacturerData",
344 G_VARIANT_TYPE_ARRAY);
346 if ((manufacturer_data_len == 0) ||
347 manufacturer_data_len != g_variant_get_size(tmp_value)) {
348 ERR("manufacturer data length doesn't match");
349 manufacturer_data_len = 0;
350 manufacturer_data = NULL;
352 manufacturer_data = g_malloc0(manufacturer_data_len);
353 g_variant_get(tmp_value, "ay", &value_iter);
354 while (g_variant_iter_loop(value_iter, "y", &m_value))
355 manufacturer_data[i++] = m_value;
357 g_variant_unref(tmp_value);
359 INFO("manufacture data is not a G_VARIANT_TYPE_ARRAY ");
360 manufacturer_data_len = 0;
361 manufacturer_data = NULL;
363 /*minimum Size of the samsung specific manufacturer data is greater than 30 */
364 if (manufacturer_data_len < 30) {
365 g_free(manufacturer_data);
368 if (manufacturer_data[0] != 0x00 || manufacturer_data[1] != 0x75) {
369 DBG("This is not a samsung specific manufaturer data");
370 g_free(manufacturer_data);
374 /* 2 samsung (0x00 0x75) + 1 (control and version) + 1 (service ID) +
375 1 (discovery version) + 1 (associated service ID)
376 2 (Proxamity and locality) + 2 (Device type and icon) */
380 memcpy(auth_info, &(manufacturer_data[cursor]), 5);
382 g_free(manufacturer_data);
385 static gboolean __bt_hal_pincode_request(GapAgentPrivate *agent, GDBusProxy *device)
387 uint32_t device_class;
388 const gchar *address;
389 unsigned char auth_info[5] = {0, };
391 GVariant *reply = NULL;
392 GVariant *reply_temp = NULL;
396 reply_temp = __bt_hal_service_getall(device, BT_HAL_DEVICE_INTERFACE);
398 if (reply_temp == NULL) {
399 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
404 g_variant_get(reply_temp, "(@a{sv})", &reply); /* Format of reply a{sv}*/
406 tmp_value = g_variant_lookup_value(reply, "Class", G_VARIANT_TYPE_UINT32);
407 g_variant_get(tmp_value, "u", &device_class);
408 G_VARIANT_UNREF(tmp_value);
410 tmp_value = g_variant_lookup_value(reply, "Address", G_VARIANT_TYPE_STRING);
411 g_variant_get(tmp_value, "s", &address);
412 G_VARIANT_UNREF(tmp_value);
414 tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
415 g_variant_get(tmp_value, "s", &name);
416 G_VARIANT_UNREF(tmp_value);
421 if (headed_plugin_info->plugin_headed_enabled) {
422 __bt_hal_get_auth_info(reply, (char *)auth_info);
423 if (__bt_hal_device_is_hid_keyboard(device_class)) {
424 char str_passkey[BT_HAL_PASSKEY_MAX_LENGTH + 1] = { 0 };
426 DBG("Device is HID Keyboard");
427 if (__bt_hal_device_generate_passkey(str_passkey,
428 BT_HAL_PASSKEY_MAX_LENGTH) != 0) {
429 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT,
434 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT,
437 DBG("Launch BT Syspopup");
438 headed_plugin_info->headed_plugin->bt_launch_system_popup(
439 BT_HAL_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST,
440 name, auth_info, str_passkey, NULL, _gap_agent_get_path(agent));
441 } else if (__bt_hal_device_is_auto_response(device_class, address, name)) {
442 DBG("Device is of Type Auto response, send event to HAL");
443 __bt_hal_send_pin_request_event(address, name, device_class);
444 } else if (pincode_notification) {
445 DBG("pincode_notification is enabled, send event to HAL");
446 __bt_hal_send_pin_request_event(address, name, device_class);
448 DBG("Device is not of Auto response class, Show PIN Entry");
449 headed_plugin_info->headed_plugin->bt_launch_system_popup(
450 BT_HAL_AGENT_EVENT_PIN_REQUEST, name, auth_info,
451 NULL, NULL, _gap_agent_get_path(agent));
454 INFO("Plugin Headed not Enabled");
455 __bt_hal_send_pin_request_event(address, name, device_class);
459 g_variant_unref(reply);
460 g_variant_unref(reply_temp);
461 __bt_hal_agent_release_memory();
468 /* BT_SSP_VARIANT_PASSKEY_CONFIRMATION */
469 /* BT_SSP_VARIANT_PASSKEY_NOTIFICATION */
470 /* BT_SSP_VARIANT_PASSKEY_ENTRY */
471 /* BT_SSP_VARIANT_CONSENT */
473 static void __bt_hal_send_ssp_request_events(const gchar *address,
477 unsigned char variant)
479 struct hal_ev_ssp_request ev;
480 memset(&ev, 0, sizeof(ev));
481 DBG("sizeof ev [%d]", sizeof(ev));
483 DBG("Remote Device address [%s]", address);
484 DBG("Remote Device Name [%s]", name);
485 DBG("Remote Device passkey [%d]", passkey);
486 DBG("Remote Device pairing variant [0x%x]", variant);
487 DBG("Remote Device cod [%d]", cod);
489 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
491 memcpy(ev.name, name, strlen(name)+1);
492 ev.class_of_dev = cod;
493 ev.pairing_variant = variant;
494 ev.passkey = passkey;
496 handle_stack_msg event_cb = _bt_hal_get_stack_message_handler();
498 DBG("Sending SSP type [%d]", variant);
499 event_cb(HAL_EV_SSP_REQUEST, (void*)&ev, sizeof(ev));
506 static gboolean __bt_hal_display_request(GapAgentPrivate *agent, GDBusProxy *device,
509 const gchar *address;
511 unsigned char auth_info[5] = {0, };
513 uint32_t device_class;
514 GVariant *reply = NULL;
515 GVariant *reply_temp = NULL;
516 GVariant *tmp_value = NULL;
519 reply_temp = __bt_hal_service_getall(device, BT_HAL_DEVICE_INTERFACE);
520 if (reply_temp == NULL) {
521 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
526 g_variant_get(reply_temp, "(@a{sv})", &reply); /* Format of reply a{sv}*/
528 tmp_value = g_variant_lookup_value(reply, "Address", G_VARIANT_TYPE_STRING);
529 g_variant_get(tmp_value, "s", &address);
530 G_VARIANT_UNREF(tmp_value);
532 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
536 tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
537 g_variant_get(tmp_value, "s", &name);
538 G_VARIANT_UNREF(tmp_value);
540 tmp_value = g_variant_lookup_value(reply, "Class", G_VARIANT_TYPE_UINT32);
541 g_variant_get(tmp_value, "u", &device_class);
542 G_VARIANT_UNREF(tmp_value);
547 str_passkey = g_strdup_printf("%d", passkey);
549 __bt_hal_get_auth_info(reply, (char *)auth_info);
551 DBG("KEYBOARD_PASSKEY_REQUEST");
553 if (passkey_display_notification) {
554 DBG("passkey_display_notification is enabled, send event to HAL");
555 __bt_hal_send_ssp_request_events(address, name, passkey, device_class,
556 BT_SSP_VARIANT_PASSKEY_NOTIFICATION);
557 } else if (headed_plugin_info->plugin_headed_enabled) {
558 INFO("Plugin Headed Enabled");
559 headed_plugin_info->headed_plugin->bt_launch_system_popup(BT_HAL_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST, name,
560 auth_info, str_passkey, NULL, _gap_agent_get_path(agent));
562 INFO("Plugin Headed not Enabled");
563 __bt_hal_send_ssp_request_events(address, name, passkey, device_class,
564 BT_SSP_VARIANT_PASSKEY_NOTIFICATION);
569 g_variant_unref(reply);
570 g_variant_unref(reply_temp);
571 __bt_hal_agent_release_memory();
578 static gboolean __bt_hal_passkey_request(GapAgentPrivate *agent, GDBusProxy *device)
580 const gchar *address;
582 unsigned char auth_info[5] = {0, };
583 uint32_t device_class;
584 GVariant *reply = NULL;
585 GVariant *reply_temp = NULL;
589 reply_temp = __bt_hal_service_getall(device, BT_HAL_DEVICE_INTERFACE);
591 if (reply_temp == NULL) {
592 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
597 g_variant_get(reply_temp, "(@a{sv})", &reply); /* Format of reply a{sv}*/
599 tmp_value = g_variant_lookup_value(reply, "Address", G_VARIANT_TYPE_STRING);
600 g_variant_get(tmp_value, "s", &address);
601 G_VARIANT_UNREF(tmp_value);
603 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
607 tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
608 g_variant_get(tmp_value, "s", &name);
609 G_VARIANT_UNREF(tmp_value);
611 tmp_value = g_variant_lookup_value(reply, "Class", G_VARIANT_TYPE_UINT32);
612 g_variant_get(tmp_value, "u", &device_class);
613 G_VARIANT_UNREF(tmp_value);
618 DBG("PASSKEY_REQUEST");
620 __bt_hal_get_auth_info(reply, (char *)auth_info);
622 if (headed_plugin_info->plugin_headed_enabled) {
623 headed_plugin_info->headed_plugin->bt_launch_system_popup(BT_HAL_AGENT_EVENT_PASSKEY_REQUEST, name, auth_info,
624 NULL, NULL, _gap_agent_get_path(agent));
626 __bt_hal_send_ssp_request_events(address, name, 0, device_class,
627 BT_SSP_VARIANT_PASSKEY_ENTRY);
631 g_variant_unref(reply);
632 g_variant_unref(reply_temp);
633 __bt_hal_agent_release_memory();
640 static gboolean __bt_hal_confirm_request(GapAgentPrivate *agent, GDBusProxy *device,
643 const gchar *address;
646 uint32_t device_class;
647 GVariant *reply_temp = NULL;
648 GVariant *reply = NULL;
650 DBG("+ passkey[%.6d]", passkey);
651 DBG("Agent Path [%s]", agent->path);
653 snprintf(str_passkey, sizeof(str_passkey), "%.6d", passkey);
655 reply_temp = __bt_hal_service_getall(device, BT_HAL_DEVICE_INTERFACE);
657 if (reply_temp == NULL) {
658 ERR("####Device doesn't exist####");
659 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
663 g_variant_get(reply_temp, "(@a{sv})", &reply); /* Format of reply a{sv}*/
665 tmp_value = g_variant_lookup_value(reply, "Address", G_VARIANT_TYPE_STRING);
666 g_variant_get(tmp_value, "s", &address);
667 G_VARIANT_UNREF(tmp_value);
669 tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
670 g_variant_get(tmp_value, "s", &name);
671 G_VARIANT_UNREF(tmp_value);
673 tmp_value = g_variant_lookup_value(reply, "Class", G_VARIANT_TYPE_UINT32);
674 g_variant_get(tmp_value, "u", &device_class);
675 G_VARIANT_UNREF(tmp_value);
680 if (headed_plugin_info->plugin_headed_enabled) {
681 unsigned char auth_info[5] = {0, };
683 DBG("LAUNCH SYSPOPUP");
684 DBG("Name [%s]", name);
685 DBG("Passkey [%s]", str_passkey);
687 __bt_hal_get_auth_info(reply, (char *)auth_info);
688 headed_plugin_info->headed_plugin->bt_launch_system_popup(BT_HAL_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name,
689 auth_info, str_passkey, NULL,
690 _gap_agent_get_path(agent));
692 DBG("Headless Confirmation");
693 __bt_hal_send_ssp_request_events(address, name, passkey,
694 device_class, BT_SSP_VARIANT_PASSKEY_CONFIRMATION);
698 g_variant_unref(reply);
699 g_variant_unref(reply_temp);
700 __bt_hal_agent_release_memory();
705 static gboolean __bt_hal_authorize_request(GapAgentPrivate *agent, GDBusProxy *device,
708 const gchar *address;
712 GVariant *reply = NULL;
713 GVariant *reply_temp = NULL;
716 DBG("Authorize Request from Bluez Stack: UUID [%s]", uuid);
718 reply_temp = __bt_hal_service_getall(device, BT_HAL_DEVICE_INTERFACE);
719 if (reply_temp == NULL) {
720 gap_agent_reply_authorize(agent, GAP_AGENT_REJECT, NULL);
724 g_variant_get(reply_temp, "(@a{sv})", &reply); /* Format of reply a{sv}*/
726 tmp_value = g_variant_lookup_value(reply, "Address", G_VARIANT_TYPE_STRING);
727 g_variant_get(tmp_value, "s", &address);
728 G_VARIANT_UNREF(tmp_value);
730 gap_agent_reply_authorize(agent, GAP_AGENT_REJECT, NULL);
734 tmp_value = g_variant_lookup_value(reply, "Alias", G_VARIANT_TYPE_STRING);
735 g_variant_get(tmp_value, "s", &name);
736 G_VARIANT_UNREF(tmp_value);
740 tmp_value = g_variant_lookup_value(reply, "Trusted", G_VARIANT_TYPE_BOOLEAN);
741 g_variant_get(tmp_value, "b", &trust);
742 G_VARIANT_UNREF(tmp_value);
744 tmp_value = g_variant_lookup_value(reply, "Paired", G_VARIANT_TYPE_BOOLEAN);
745 g_variant_get(tmp_value, "b", &paired);
746 G_VARIANT_UNREF(tmp_value);
747 if ((paired == FALSE) && (trust == FALSE)) {
748 ERR("No paired & No trusted device");
749 gap_agent_reply_authorize(agent, GAP_AGENT_REJECT, NULL);
753 INFO("Authorization request for device [%s] Service:[%s]\n", address, uuid);
756 INFO("Trusted device, so authorize\n");
757 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT, NULL);
760 INFO("Device is not Trusted, so prompt user to accept or reject authorization \n");
763 if (!strcasecmp(uuid, BT_HAL_HFP_AUDIO_GATEWAY_UUID) ||
764 !strcasecmp(uuid, BT_HAL_HSP_AUDIO_GATEWAY_UUID) ||
765 !strcasecmp(uuid, BT_HAL_HFP_HF_UUID) ||
766 !strcasecmp(uuid, BT_HAL_HSP_HS_UUID) ||
767 !strcasecmp(uuid, BT_HAL_A2DP_PROFILE_UUID) ||
768 !strcasecmp(uuid, BT_HAL_HID_UUID) ||
769 !strcasecmp(uuid, BT_HAL_HID_DEVICE_UUID) ||
770 !strcasecmp(uuid, BT_HAL_SAP_UUID_OLD) ||
771 !strcasecmp(uuid, BT_HAL_SAP_UUID_NEW) ||
773 !strcasecmp(uuid, BT_HAL_IOTIVITY_UUID) ||
775 !strcasecmp(uuid, BT_HAL_AVRCP_TARGET_UUID)) {
776 DBG("Authorization for UUID: %s, send event", uuid);
777 __bt_hal_send_authorize_request_event(address, uuid);
782 if (!strcasecmp(uuid, BT_HAL_OPP_UUID) &&
783 (NULL != _bt_hal_gap_agent_find_osp_server_by_type(
784 agent->osp_servers, BT_OSP_SERVER_OBEX))) {
785 INFO("OSP server for OPP found, send event");
786 __bt_hal_send_authorize_request_event(address, uuid);
790 if (_is_rfcomm_server_uuid(uuid)) {
791 __bt_hal_send_rfcomm_authorize_request_event(address, uuid);
796 if (trust || !headed_plugin_info->plugin_headed_enabled) {
797 INFO("Trusted or Headless device, so authorize\n");
798 gap_agent_reply_authorize(agent,
799 GAP_AGENT_ACCEPT, NULL);
804 if (headed_plugin_info->plugin_headed_enabled) {
805 unsigned char auth_info[5] = {0, };
806 int request_type = BT_HAL_AGENT_EVENT_AUTHORIZE_REQUEST;
808 __bt_hal_get_auth_info(reply, (char *)auth_info);
810 if (!strcasecmp(uuid, BT_HAL_OPP_UUID))
811 request_type = BT_HAL_AGENT_EVENT_EXCHANGE_REQUEST;
812 else if (!strcasecmp(uuid, BT_HAL_PBAP_UUID))
813 request_type = BT_HAL_AGENT_EVENT_PBAP_REQUEST;
814 else if (!strcasecmp(uuid, BT_HAL_MAP_UUID))
815 request_type = BT_HAL_AGENT_EVENT_MAP_REQUEST;
817 headed_plugin_info->headed_plugin->bt_launch_system_popup(request_type, name, auth_info, NULL, NULL,
818 _gap_agent_get_path(agent));
822 g_variant_unref(reply);
823 g_variant_unref(reply_temp);
824 __bt_hal_agent_release_memory();
830 static gboolean __bt_hal_authorize_cancel_request(GapAgentPrivate *agent,
833 DBG("On Going Authorization is cancelled by remote [%s]", address);
834 gap_agent_reply_authorize(agent, GAP_AGENT_CANCEL, NULL);
836 if (headed_plugin_info->plugin_headed_enabled)
837 headed_plugin_info->headed_plugin->bt_destroy_popup_all();
839 __bt_hal_agent_release_memory();
843 static gboolean __bt_hal_pairing_cancel_request(GapAgentPrivate *agent, const char *address)
845 DBG("On Going Pairing is cancelled by remote [%s]", address);
847 if (headed_plugin_info->plugin_headed_enabled)
848 headed_plugin_info->headed_plugin->bt_destroy_popup_all();
850 __bt_hal_agent_release_memory();
854 static gboolean __bt_hal_device_is_hid_keyboard(unsigned int dev_class)
856 switch ((dev_class & 0x1f00) >> 8) {
858 switch ((dev_class & 0xc0) >> 6) {
860 /* input-keyboard" */
869 static int __bt_hal_device_generate_passkey(char *passkey, int size)
874 unsigned int value = 0;
882 random_fd = open("/dev/urandom", O_RDONLY);
887 for (i = 0; i < size; i++) {
888 len = read(random_fd, &value, sizeof(value));
890 passkey[i] = '0' + (value % 10);
895 DBG("passkey: %s", passkey);
900 static gboolean __bt_hal_find_device_by_address_exactname(char *buffer,
906 pch = strtok_r(buffer, "= ,", &last);
911 while ((pch = strtok_r(NULL, ",", &last))) {
912 if (0 == g_strcmp0(pch, address)) {
913 DBG("Match found\n");
920 static gboolean __bt_hal_find_device_by_partial_name(char *buffer,
921 const char *partial_name)
926 pch = strtok_r(buffer, "= ,", &last);
931 while ((pch = strtok_r(NULL, ",", &last))) {
932 if (g_str_has_prefix(partial_name, pch)) {
933 DBG("Match found\n");
940 static gboolean __bt_hal_device_is_device_blacklisted(const char *address,
952 fp = fopen(BT_HAL_AGENT_AUTO_PAIR_BLACKLIST_FILE, "r");
955 ERR("Unable to open blacklist file");
959 fseek(fp, 0, SEEK_END);
962 DBG("size is not a positive number");
969 buffer = g_malloc0(sizeof(char) * size);
970 /* Fix : NULL_RETURNS */
971 if (buffer == NULL) {
972 ERR("Fail to allocate memory");
976 result = fread((char *)buffer, 1, size, fp);
978 if (result != size) {
984 DBG("Buffer = %s", buffer);
986 lines = g_strsplit_set(buffer, BT_HAL_AGENT_NEW_LINE, 0);
990 ERR("No lines in the file");
994 for (i = 0; lines[i] != NULL; i++) {
995 if (g_str_has_prefix(lines[i], "AddressBlacklist"))
996 if (__bt_hal_find_device_by_address_exactname(
999 if (g_str_has_prefix(lines[i], "ExactNameBlacklist"))
1000 if (__bt_hal_find_device_by_address_exactname(
1003 if (g_str_has_prefix(lines[i], "PartialNameBlacklist"))
1004 if (__bt_hal_find_device_by_partial_name(lines[i],
1007 if (g_str_has_prefix(lines[i], "KeyboardAutoPair"))
1008 if (__bt_hal_find_device_by_address_exactname(
1016 DBG("Found the device");
1021 static gboolean __bt_hal_device_is_auto_response(uint32_t dev_class,
1022 const gchar *address, const gchar *name)
1024 gboolean is_headset = FALSE;
1025 gboolean is_mouse = FALSE;
1026 char lap_address[BT_HAL_LOWER_ADDRESS_LENGTH];
1028 DBG("bt_agent_is_headset_class, %d +", dev_class);
1030 if (address == NULL)
1033 switch ((dev_class & 0x1f00) >> 8) {
1035 switch ((dev_class & 0xfc) >> 2) {
1045 case 0x0b: /* VCR */
1046 case 0x0c: /* Video Camera */
1047 case 0x0d: /* Camcorder */
1050 /* Other audio device */
1056 switch (dev_class & 0xff) {
1057 case 0x80: /* 0x80: Pointing device(Mouse) */
1061 case 0x40: /* 0x40: input device (BT keyboard) */
1063 /* Get the LAP(Lower Address part) */
1064 g_strlcpy(lap_address, address, sizeof(lap_address));
1066 /* Need to Auto pair the blacklisted Keyboard */
1067 if (__bt_hal_device_is_device_blacklisted(lap_address, name) != TRUE) {
1068 DBG("Device is not black listed\n");
1071 ERR("Device is black listed\n");
1077 if ((!is_headset) && (!is_mouse))
1080 /* Get the LAP(Lower Address part) */
1081 g_strlcpy(lap_address, address, sizeof(lap_address));
1083 DBG("Device address = %s\n", address);
1084 DBG("Address 3 byte = %s\n", lap_address);
1086 if (__bt_hal_device_is_device_blacklisted(lap_address, name)) {
1087 ERR("Device is black listed\n");
1094 static GVariant *__bt_hal_service_getall(GDBusProxy *device, const char *interface)
1096 GError *error = NULL;
1099 reply = g_dbus_proxy_call_sync(device,
1100 "GetAll", g_variant_new("(s)", interface),
1101 G_DBUS_CALL_FLAGS_NONE, -1,
1103 if (reply == NULL) {
1104 ERR("GetAll dBUS-RPC failed");
1106 ERR("D-Bus API failure: errCode[%x], message[%s]",
1107 error->code, error->message);
1108 g_clear_error(&error);
1117 static void __bt_hal_agent_release_memory(void)
1119 /* Release Malloc Memory*/
1122 /* Release Stack Memory*/
1126 static inline void stack_trim(void)
1132 unsigned int stacktop;
1135 asm volatile ("mov %0,sp " : "=r"(sp));
1137 sprintf(buf, "/proc/%d/maps", getpid());
1138 file = fopen(buf, "r");
1139 while (fgets(buf, BUF_SIZE, file) != NULL) {
1140 if (strstr(buf, "[stack]")) {
1148 sscanf(buf, "%x-", &stacktop);
1149 if (madvise((void *)PAGE_ALIGN(stacktop), PAGE_ALIGN(sp) - stacktop,
1151 perror("stack madvise fail");