2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include <stacktrim.h>
24 #include <bundle_internal.h>
26 #include <tethering.h>
28 #include "bt-internal-types.h"
29 #include "bt-service-common.h"
30 #include "bt-service-agent.h"
31 #include "bt-service-gap-agent.h"
32 #include "bt-service-adapter.h"
33 #include "bt-service-event.h"
34 #include "bt-service-rfcomm-server.h"
35 #include "bt-service-device.h"
36 #include "bt-service-audio.h"
38 #ifdef TIZEN_FEATURE_BT_DPM
39 #include "bt-service-dpm.h"
42 #define BT_APP_AUTHENTICATION_TIMEOUT 35
43 #define BT_APP_AUTHORIZATION_TIMEOUT 15
45 #define HFP_AUDIO_GATEWAY_UUID "0000111f-0000-1000-8000-00805f9b34fb"
46 #define HSP_AUDIO_GATEWAY_UUID "00001112-0000-1000-8000-00805f9b34fb"
47 #define A2DP_UUID "0000110D-0000-1000-8000-00805F9B34FB"
48 #define AVRCP_TARGET_UUID "0000110c-0000-1000-8000-00805f9b34fb"
49 #define OPP_UUID "00001105-0000-1000-8000-00805f9b34fb"
50 #define FTP_UUID "00001106-0000-1000-8000-00805f9b34fb"
51 #define SPP_UUID "00001101-0000-1000-8000-00805f9b34fb"
52 #define PBAP_UUID "0000112f-0000-1000-8000-00805f9b34fb"
53 #define MAP_UUID "00001132-0000-1000-8000-00805f9b34fb"
54 #define NAP_UUID "00001116-0000-1000-8000-00805f9b34fb"
55 #define GN_UUID "00001117-0000-1000-8000-00805f9b34fb"
56 #define BNEP_UUID "0000000f-0000-1000-8000-00805f9b34fb"
57 #define HID_UUID "00001124-0000-1000-8000-00805f9b34fb"
58 #define HID_DEVICE_UUID "00001124-0000-1000-8000-00805f9b43bf"
59 #define SAP_UUID_OLD "a49eb41e-cb06-495c-9f4f-bb80a90cdf00"
60 #define SAP_UUID_NEW "a49eb41e-cb06-495c-9f4f-aa80a90cdf4a"
61 #define IOTIVITY_UUID "12341234-1C25-481F-9DFB-59193D238280"
63 #define BT_AGENT_OBJECT "/org/bluez/agent/frwk_agent"
65 #define BT_AGENT_INTERFACE "org.bluez.Agent1"
67 #define BT_AGENT_SIGNAL_RFCOMM_AUTHORIZE "RfcommAuthorize"
68 #define BT_AGENT_SIGNAL_OBEX_AUTHORIZE "ObexAuthorize"
70 #define BT_PASSKEY_MAX_LENGTH 4
72 #define BT_AGENT_SYSPOPUP_TIMEOUT_FOR_MULTIPLE_POPUPS 200
73 #define BT_AGENT_SYSPOPUP_MAX_ATTEMPT 3
74 #define BT_PAN_MAX_CONNECTION 4
76 extern guint nap_connected_device_count;
78 static char *passkey_watcher = NULL;
80 #define G_VARIANT_UNREF(variant) \
81 g_variant_unref(variant); \
84 static int __bt_agent_is_auto_response(uint32_t dev_class, const gchar *address,
86 static gboolean __bt_agent_is_hid_keyboard(uint32_t dev_class);
87 static int __bt_agent_generate_passkey(char *passkey, int size);
89 static void __bt_agent_release_memory(void)
91 /* Release Malloc Memory*/
94 /* Release Stack Memory*/
98 static GVariant *__bt_service_getall(GDBusProxy *device, const char *interface)
100 GError *error = NULL;
103 reply = g_dbus_proxy_call_sync(device,
104 "GetAll", g_variant_new("(s)", interface),
105 G_DBUS_CALL_FLAGS_NONE, -1,
108 ERR("GetAll dBUS-RPC failed");
110 ERR("D-Bus API failure: errCode[%x], message[%s]",
111 error->code, error->message);
112 g_clear_error(&error);
120 static gboolean __pincode_request(GapAgentPrivate *agent, GDBusProxy *device)
122 uint32_t device_class;
123 gchar *address = NULL;
124 unsigned char auth_info[5] = {0, };
126 GVariant *reply = NULL;
127 GVariant *reply_temp = NULL;
129 char pin_code[BLUETOOTH_PIN_CODE_MAX_LENGTH + 1];
130 int ret = BLUETOOTH_ERROR_NONE;
131 #ifdef TIZEN_FEATURE_BT_DPM
132 int pairing_state = DPM_STATUS_ERROR;
137 #ifdef TIZEN_FEATURE_BT_DPM
138 _bt_dpm_get_bluetooth_pairing_state(&pairing_state);
139 if (pairing_state == DPM_RESTRICTED) {
140 BT_ERR("Not allow to pair the device");
141 gap_agent_reply_confirmation(agent, GAP_AGENT_REJECT, NULL);
142 __bt_agent_release_memory();
147 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
149 if (reply_temp == NULL) {
150 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
155 g_variant_get(reply_temp, "(@a{sv})", &reply); /* Format of reply a{sv}*/
157 tmp_value = g_variant_lookup_value(reply, "Class", G_VARIANT_TYPE_UINT32);
158 g_variant_get(tmp_value, "u", &device_class);
159 G_VARIANT_UNREF(tmp_value);
161 tmp_value = g_variant_lookup_value(reply, "Address", G_VARIANT_TYPE_STRING);
162 g_variant_get(tmp_value, "s", &address);
163 G_VARIANT_UNREF(tmp_value);
165 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
169 tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
170 g_variant_get(tmp_value, "s", &name);
171 G_VARIANT_UNREF(tmp_value);
173 BT_DBG("Replacing the name with address");
174 name = g_strdup(address);
176 BT_INFO("Name = %s, Address = %s, Class = 0x%x", name, address, device_class);
177 if (name[0] == '\0') {
179 BT_DBG("Name[0]=NULL, Replacing the name with address");
180 name = g_strdup(address);
184 __bt_get_auth_info(reply, (char *)auth_info);
185 if (_bt_is_device_creating() == TRUE &&
186 _bt_is_bonding_device_address(address) == TRUE &&
187 __bt_agent_is_auto_response(device_class, address, name)) {
188 BT_DBG("0000 Auto Pair");
189 /* Use Fixed PIN "0000" for basic pairing */
190 _bt_set_autopair_status_in_bonding_info(TRUE);
191 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, "0000",
193 } else if (__bt_agent_is_hid_keyboard(device_class)) {
194 BT_DBG("HID Keyboard");
195 char str_passkey[BT_PASSKEY_MAX_LENGTH + 1] = { 0 };
197 if (__bt_agent_generate_passkey(str_passkey,
198 BT_PASSKEY_MAX_LENGTH) != 0) {
199 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT,
204 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT,
207 if (headed_plugin_info->plugin_headed_enabled) {
208 headed_plugin_info->headed_plugin->bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST,
209 name, auth_info, str_passkey, NULL, _gap_agent_get_path(agent));
211 GVariant *param = NULL;
212 param = g_variant_new("(isss)", ret, address, name, str_passkey);
213 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY, param);
215 } else if (_bt_get_device_pin_code(address, pin_code)
216 == BLUETOOTH_ERROR_NONE) {
217 BT_DBG("Use stored PIN code(%s)", pin_code);
218 gap_agent_reply_pin_code(agent, GAP_AGENT_ACCEPT, pin_code,
222 if (headed_plugin_info->plugin_headed_enabled) {
223 BT_DBG("Show Pin entry");
224 headed_plugin_info->headed_plugin->bt_launch_system_popup(BT_AGENT_EVENT_PIN_REQUEST, name, auth_info,
225 NULL, NULL, _gap_agent_get_path(agent));
227 BT_INFO("Plugin Headed not Enabled");
228 GVariant *param = NULL;
229 param = g_variant_new("(iss)", ret, address, name);
230 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_PIN_REQUEST, param);
235 g_variant_unref(reply);
236 g_variant_unref(reply_temp);
239 __bt_agent_release_memory();
245 static gboolean __passkey_request(GapAgentPrivate *agent, GDBusProxy *device)
247 gchar *address = NULL;
249 unsigned char auth_info[5] = {0, };
250 GVariant *reply = NULL;
251 GVariant *reply_temp = NULL;
253 int ret = BLUETOOTH_ERROR_NONE;
254 #ifdef TIZEN_FEATURE_BT_DPM
255 int pairing_state = DPM_STATUS_ERROR;
260 #ifdef TIZEN_FEATURE_BT_DPM
261 _bt_dpm_get_bluetooth_pairing_state(&pairing_state);
262 if (pairing_state == DPM_RESTRICTED) {
263 BT_ERR("Not allow to pair the device");
264 gap_agent_reply_confirmation(agent, GAP_AGENT_REJECT, NULL);
265 __bt_agent_release_memory();
270 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
272 if (reply_temp == NULL) {
273 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
278 g_variant_get(reply_temp, "(@a{sv})", &reply); /* Format of reply a{sv}*/
280 tmp_value = g_variant_lookup_value(reply, "Address", G_VARIANT_TYPE_STRING);
281 g_variant_get(tmp_value, "s", &address);
282 G_VARIANT_UNREF(tmp_value);
284 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
288 tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
289 g_variant_get(tmp_value, "s", &name);
290 G_VARIANT_UNREF(tmp_value);
292 name = g_strdup(address);
294 __bt_get_auth_info(reply, (char *)auth_info);
296 if (headed_plugin_info->plugin_headed_enabled) {
297 headed_plugin_info->headed_plugin->bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_REQUEST, name, auth_info,
298 NULL, NULL, _gap_agent_get_path(agent));
300 BT_INFO("Plugin Headed not Enabled");
301 GVariant *param = NULL;
302 param = g_variant_new("(iss)", ret, address, name);
303 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_PASSKEY_REQUEST, param);
308 g_variant_unref(reply);
309 g_variant_unref(reply_temp);
312 __bt_agent_release_memory();
318 static gboolean __display_request(GapAgentPrivate *agent, GDBusProxy *device,
321 gchar *address = NULL;
323 unsigned char auth_info[5] = {0, };
325 GVariant *reply = NULL;
326 GVariant *reply_temp = NULL;
327 GVariant *tmp_value = NULL;
328 int ret = BLUETOOTH_ERROR_NONE;
332 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
333 if (reply_temp == NULL) {
334 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
339 g_variant_get(reply_temp, "(@a{sv})", &reply); /* Format of reply a{sv}*/
341 tmp_value = g_variant_lookup_value(reply, "Address", G_VARIANT_TYPE_STRING);
342 g_variant_get(tmp_value, "s", &address);
343 G_VARIANT_UNREF(tmp_value);
345 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
349 tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
350 g_variant_get(tmp_value, "s", &name);
351 G_VARIANT_UNREF(tmp_value);
353 name = g_strdup(address);
355 __bt_get_auth_info(reply, (char *)auth_info);
357 str_passkey = g_strdup_printf("%06d", passkey);
359 GVariant *param = NULL;
360 param = g_variant_new("(ss)", address, str_passkey);
362 if (passkey_watcher) {
363 BT_INFO("Send passkey to %s", passkey_watcher);
364 _bt_send_event_to_dest(passkey_watcher, BT_ADAPTER_EVENT,
365 BLUETOOTH_EVENT_PASSKEY_NOTIFICATION, param);
367 if (headed_plugin_info->plugin_headed_enabled) {
368 BT_INFO("Plugin Headed Enabled");
369 headed_plugin_info->headed_plugin->bt_launch_system_popup(BT_AGENT_EVENT_KEYBOARD_PASSKEY_REQUEST, name,
370 auth_info, str_passkey, NULL, _gap_agent_get_path(agent));
372 BT_INFO("Plugin Headed not Enabled");
373 GVariant *param = NULL;
374 param = g_variant_new("(isss)", ret, address, name, str_passkey);
375 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_KEYBOARD_PASSKEY_DISPLAY, param);
382 g_variant_unref(reply);
383 g_variant_unref(reply_temp);
386 __bt_agent_release_memory();
392 static gboolean __confirm_request(GapAgentPrivate *agent, GDBusProxy *device,
395 gchar *address = NULL;
397 unsigned char auth_info[5] = {0, };
399 GVariant *reply_temp = NULL;
400 GVariant *reply = NULL;
402 int ret = BLUETOOTH_ERROR_NONE;
403 #ifdef TIZEN_FEATURE_BT_DPM
404 int pairing_state = DPM_STATUS_ERROR;
406 BT_DBG("+ passkey[%.6d]", passkey);
408 #ifdef TIZEN_FEATURE_BT_DPM
409 _bt_dpm_get_bluetooth_pairing_state(&pairing_state);
410 if (pairing_state == DPM_RESTRICTED) {
411 BT_ERR("Not allow to pair the device");
412 gap_agent_reply_confirmation(agent, GAP_AGENT_REJECT, NULL);
413 __bt_agent_release_memory();
418 snprintf(str_passkey, sizeof(str_passkey), "%.6d", passkey);
420 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
422 if (reply_temp == NULL) {
423 BT_ERR("Device doesn't exist");
424 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
429 g_variant_get(reply_temp, "(@a{sv})", &reply); /* Format of reply a{sv}*/
431 tmp_value = g_variant_lookup_value(reply, "Address", G_VARIANT_TYPE_STRING);
432 g_variant_get(tmp_value, "s", &address);
433 G_VARIANT_UNREF(tmp_value);
435 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
439 tmp_value = g_variant_lookup_value(reply, "Name", G_VARIANT_TYPE_STRING);
440 g_variant_get(tmp_value, "s", &name);
441 G_VARIANT_UNREF(tmp_value);
443 name = g_strdup(address);
444 __bt_get_auth_info(reply, (char *)auth_info);
446 if (headed_plugin_info->plugin_headed_enabled) {
447 BT_DBG("LAUNCH SYSPOPUP");
448 headed_plugin_info->headed_plugin->bt_launch_system_popup(BT_AGENT_EVENT_PASSKEY_CONFIRM_REQUEST, name,
449 auth_info, str_passkey, NULL,
450 _gap_agent_get_path(agent));
452 BT_DBG("Headless Confirmation");
453 GVariant *param = NULL;
454 param = g_variant_new("(isss)", ret, address, name, str_passkey);
455 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_PASSKEY_CONFIRM_REQUEST, param);
459 g_variant_unref(reply);
460 g_variant_unref(reply_temp);
463 __bt_agent_release_memory();
469 static gboolean __pairing_cancel_request(GapAgentPrivate *agent, const char *address)
471 BT_DBG("On Going Pairing is cancelled by remote\n");
473 if (headed_plugin_info->plugin_headed_enabled)
474 headed_plugin_info->headed_plugin->bt_destroy_popup_all();
476 __bt_agent_release_memory();
481 static gboolean __a2dp_authorize_request_check(void)
483 /* Check for existing Media device to disconnect */
484 return _bt_is_headset_type_connected(BT_AUDIO_A2DP, NULL);
487 static gboolean __authorize_request(GapAgentPrivate *agent, GDBusProxy *device,
490 gchar *address = NULL;
492 unsigned char auth_info[5] = {0, };
494 GVariant *reply = NULL;
495 GVariant *reply_temp = NULL;
498 int result = BLUETOOTH_ERROR_NONE;
499 int request_type = BT_AGENT_EVENT_AUTHORIZE_REQUEST;
500 tethering_h tethering = NULL;
504 /* Check if already Media connection exsist */
505 if (!strcasecmp(uuid, A2DP_UUID)) {
506 gboolean ret = FALSE;
508 ret = __a2dp_authorize_request_check();
511 BT_ERR("Already one A2DP device connected \n");
512 gap_agent_reply_authorize(agent, GAP_AGENT_REJECT,
517 /* Check completed */
519 if (!strcasecmp(uuid, HFP_AUDIO_GATEWAY_UUID) ||
520 !strcasecmp(uuid, HSP_AUDIO_GATEWAY_UUID) ||
521 !strcasecmp(uuid, HFP_HS_UUID) ||
522 !strcasecmp(uuid, HSP_HS_UUID) ||
523 !strcasecmp(uuid, A2DP_UUID) ||
524 !strcasecmp(uuid, HID_UUID) ||
525 !strcasecmp(uuid, HID_DEVICE_UUID) ||
526 !strcasecmp(uuid, SAP_UUID_OLD) ||
527 !strcasecmp(uuid, SAP_UUID_NEW) ||
528 !strcasecmp(uuid, IOTIVITY_UUID) ||
529 !strcasecmp(uuid, AVRCP_TARGET_UUID)) {
530 BT_DBG("Auto accept authorization for audio device (HFP, A2DP, AVRCP) [%s]", uuid);
531 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
537 if (!strcasecmp(uuid, NAP_UUID) ||
538 !strcasecmp(uuid, GN_UUID) ||
539 !strcasecmp(uuid, BNEP_UUID)) {
541 BT_DBG("Network connection request: %s", uuid);
542 if (TIZEN_FEATURE_NETWORK_TETHERING_ENABLE) {
543 if (nap_connected_device_count >=
544 BT_PAN_MAX_CONNECTION) {
545 BT_ERR("Max connection exceeded");
549 ret = tethering_create(&tethering);
551 if (ret != TETHERING_ERROR_NONE) {
552 BT_ERR("Fail to create tethering: %d", ret);
556 enabled = tethering_is_enabled(tethering, TETHERING_TYPE_BT);
558 ret = tethering_destroy(tethering);
560 if (ret != TETHERING_ERROR_NONE)
561 BT_ERR("Fail to create tethering: %d", ret);
563 if (enabled != true) {
564 BT_ERR("BT tethering is not enabled");
569 gap_agent_reply_authorize(agent, GAP_AGENT_ACCEPT,
573 gap_agent_reply_authorize(agent, GAP_AGENT_REJECT,
579 reply_temp = __bt_service_getall(device, BT_DEVICE_INTERFACE);
580 if (reply_temp == NULL) {
581 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "",
586 g_variant_get(reply_temp, "(@a{sv})", &reply); /* Format of reply a{sv}*/
588 tmp_value = g_variant_lookup_value(reply, "Address", G_VARIANT_TYPE_STRING);
589 g_variant_get(tmp_value, "s", &address);
590 G_VARIANT_UNREF(tmp_value);
592 gap_agent_reply_pin_code(agent, GAP_AGENT_REJECT, "", NULL);
596 tmp_value = g_variant_lookup_value(reply, "Alias", G_VARIANT_TYPE_STRING);
597 g_variant_get(tmp_value, "s", &name);
598 G_VARIANT_UNREF(tmp_value);
600 name = g_strdup(address);
602 tmp_value = g_variant_lookup_value(reply, "Trusted", G_VARIANT_TYPE_BOOLEAN);
603 g_variant_get(tmp_value, "b", &trust);
604 G_VARIANT_UNREF(tmp_value);
606 __bt_get_auth_info(reply, (char *)auth_info);
608 BT_INFO("Authorization request for device [%s] Service:[%s]\n", address, uuid);
610 if (strcasecmp(uuid, OPP_UUID) == 0 &&
611 _gap_agent_exist_osp_server(agent, BT_OBEX_SERVER,
613 _bt_send_event(BT_OPP_SERVER_EVENT,
614 BLUETOOTH_EVENT_OBEX_SERVER_CONNECTION_AUTHORIZE,
615 g_variant_new("(iss)", result, address, name));
619 /* TODO: MAP? see above */
621 if (_gap_agent_exist_osp_server(agent, BT_RFCOMM_SERVER,
622 (char *)uuid) == TRUE) {
623 bt_agent_osp_server_t *osp_serv;
624 osp_serv = _gap_agent_get_osp_server(agent,
625 BT_RFCOMM_SERVER, (char *)uuid);
628 _bt_send_event(BT_RFCOMM_SERVER_EVENT,
629 BLUETOOTH_EVENT_RFCOMM_AUTHORIZE,
630 g_variant_new("(issssn)", result, address, uuid,
631 name, osp_serv->path, osp_serv->fd));
637 if (!strcasecmp(uuid, OPP_UUID))
638 request_type = BT_AGENT_EVENT_EXCHANGE_REQUEST;
639 else if (!strcasecmp(uuid, PBAP_UUID))
640 request_type = BT_AGENT_EVENT_PBAP_REQUEST;
641 else if (!strcasecmp(uuid, MAP_UUID))
642 request_type = BT_AGENT_EVENT_MAP_REQUEST;
643 /* TODO: MAP is already here */
646 BT_INFO("Trusted device, so authorize\n");
647 gap_agent_reply_authorize(agent,
648 GAP_AGENT_ACCEPT, NULL);
650 if (headed_plugin_info->plugin_headed_enabled)
651 headed_plugin_info->headed_plugin->bt_launch_system_popup(request_type, name, auth_info, NULL, NULL,
652 _gap_agent_get_path(agent));
657 g_variant_unref(reply);
660 g_variant_unref(reply_temp);
664 __bt_agent_release_memory();
670 static gboolean __authorization_cancel_request(GapAgentPrivate *agent,
673 BT_DBG("On Going Authorization is cancelled by remote\n");
675 gap_agent_reply_authorize(agent, GAP_AGENT_CANCEL, NULL);
677 if (headed_plugin_info->plugin_headed_enabled)
678 headed_plugin_info->headed_plugin->bt_destroy_popup_all();
680 __bt_agent_release_memory();
685 void _bt_destroy_agent(void *agent)
690 _gap_agent_reset_dbus((GapAgentPrivate *)agent);
695 void* _bt_create_agent(const char *path, gboolean adapter)
697 GAP_AGENT_FUNC_CB func_cb;
698 GDBusProxy *adapter_proxy;
699 GapAgentPrivate *agent;
701 adapter_proxy = _bt_get_adapter_proxy();
705 func_cb.pincode_func = __pincode_request;
706 func_cb.display_func = __display_request;
707 func_cb.passkey_func = __passkey_request;
708 func_cb.confirm_func = __confirm_request;
709 func_cb.authorize_func = __authorize_request;
710 func_cb.pairing_cancel_func = __pairing_cancel_request;
711 func_cb.authorization_cancel_func = __authorization_cancel_request;
714 agent = g_new0(GapAgentPrivate, 1);
716 _gap_agent_setup_dbus(agent, &func_cb, path, adapter_proxy);
719 if (!_gap_agent_register(agent)) {
720 _bt_destroy_agent(agent);
728 gboolean _bt_agent_register_osp_server(const gint type,
729 const char *uuid, char *path, int fd)
731 void *agent = _bt_get_adapter_agent();
735 return _gap_agent_register_osp_server(agent, type, uuid, path, fd);
739 gboolean _bt_agent_unregister_osp_server(const gint type, const char *uuid)
741 void *agent = _bt_get_adapter_agent();
746 return _gap_agent_unregister_osp_server(agent, type, uuid);
749 gboolean _bt_agent_reply_authorize(gboolean accept)
753 void *agent = _bt_get_adapter_agent();
757 accept_val = accept ? GAP_AGENT_ACCEPT : GAP_AGENT_REJECT;
759 return gap_agent_reply_authorize(agent, accept_val, NULL);
762 gboolean _bt_agent_is_canceled(void)
764 void *agent = _bt_get_adapter_agent();
768 return _gap_agent_is_canceled(agent);
771 void _bt_agent_set_canceled(gboolean value)
773 void *agent = _bt_get_adapter_agent();
777 return _gap_agent_set_canceled(agent, value);
780 int _bt_agent_reply_cancellation(void)
782 void *agent = _bt_get_adapter_agent();
785 return BLUETOOTH_ERROR_INTERNAL;
787 if (gap_agent_reply_confirmation(agent, GAP_AGENT_CANCEL, NULL) != TRUE) {
788 BT_ERR("Fail to reply agent");
789 return BLUETOOTH_ERROR_INTERNAL;
792 return BLUETOOTH_ERROR_NONE;
795 static gboolean __bt_agent_is_hid_keyboard(uint32_t dev_class)
797 switch ((dev_class & 0x1f00) >> 8) {
799 switch ((dev_class & 0xc0) >> 6) {
801 /* input-keyboard" */
810 static gboolean __bt_agent_find_device_by_address_exactname(char *buffer,
816 pch = strtok_r(buffer, "= ,", &last);
821 while ((pch = strtok_r(NULL, ",", &last))) {
822 if (0 == g_strcmp0(pch, address)) {
823 BT_DBG("Match found\n");
830 static gboolean __bt_agent_find_device_by_partial_name(char *buffer,
831 const char *partial_name)
836 pch = strtok_r(buffer, "= ,", &last);
841 while ((pch = strtok_r(NULL, ",", &last))) {
842 if (g_str_has_prefix(partial_name, pch)) {
843 BT_DBG("Match found\n");
850 static gboolean __bt_agent_is_device_blacklist(const char *address,
862 fp = fopen(BT_AGENT_AUTO_PAIR_BLACKLIST_FILE, "r");
865 BT_ERR("Unable to open blacklist file");
869 fseek(fp, 0, SEEK_END);
872 BT_DBG("size is not a positive number");
879 buffer = g_malloc0(sizeof(char) * size);
880 result = fread((char *)buffer, 1, size, fp);
882 if (result != size) {
883 BT_ERR("Read Error");
888 BT_DBG("Buffer = %s", buffer);
890 lines = g_strsplit_set(buffer, BT_AGENT_NEW_LINE, 0);
894 BT_ERR("No lines in the file");
898 for (i = 0; lines[i] != NULL; i++) {
899 if (g_str_has_prefix(lines[i], "AddressBlacklist"))
900 if (__bt_agent_find_device_by_address_exactname(
903 if (g_str_has_prefix(lines[i], "ExactNameBlacklist"))
904 if (__bt_agent_find_device_by_address_exactname(
907 if (g_str_has_prefix(lines[i], "PartialNameBlacklist"))
908 if (__bt_agent_find_device_by_partial_name(lines[i],
911 if (g_str_has_prefix(lines[i], "KeyboardAutoPair"))
912 if (__bt_agent_find_device_by_address_exactname(
920 BT_DBG("Found the device");
925 static gboolean __bt_agent_is_auto_response(uint32_t dev_class,
926 const gchar *address, const gchar *name)
928 gboolean is_headset = FALSE;
929 gboolean is_mouse = FALSE;
930 char lap_address[BT_LOWER_ADDRESS_LENGTH];
932 BT_DBG("bt_agent_is_headset_class, %d +", dev_class);
937 switch ((dev_class & 0x1f00) >> 8) {
939 switch ((dev_class & 0xfc) >> 2) {
950 case 0x0c: /* Video Camera */
951 case 0x0d: /* Camcorder */
954 /* Other audio device */
960 switch (dev_class & 0xff) {
961 case 0x80: /* 0x80: Pointing device(Mouse) */
965 case 0x40: /* 0x40: input device (BT keyboard) */
967 /* Get the LAP(Lower Address part) */
968 g_strlcpy(lap_address, address, sizeof(lap_address));
970 /* Need to Auto pair the blacklisted Keyboard */
971 if (__bt_agent_is_device_blacklist(lap_address, name) != TRUE) {
972 BT_DBG("Device is not black listed\n");
975 BT_ERR("Device is black listed\n");
981 if ((!is_headset) && (!is_mouse))
984 /* Get the LAP(Lower Address part) */
985 g_strlcpy(lap_address, address, sizeof(lap_address));
987 BT_DBG("Device address = %s\n", address);
988 BT_DBG("Address 3 byte = %s\n", lap_address);
990 if (__bt_agent_is_device_blacklist(lap_address, name)) {
991 BT_ERR("Device is black listed\n");
998 static int __bt_agent_generate_passkey(char *passkey, int size)
1003 unsigned int value = 0;
1005 if (passkey == NULL)
1011 random_fd = open("/dev/urandom", O_RDONLY);
1016 for (i = 0; i < size; i++) {
1017 len = read(random_fd, &value, sizeof(value));
1019 passkey[i] = '0' + (value % 10);
1024 BT_DBG("passkey: %s", passkey);
1029 int _bt_set_passkey_notification(const char *sender, gboolean enable)
1031 BT_INFO("Set passkey notification(sender:%s, %s)",
1032 sender, enable ? "Enable" : "Disable");
1034 g_free(passkey_watcher);
1036 passkey_watcher = g_strdup(sender);
1038 passkey_watcher = NULL;
1040 return BLUETOOTH_ERROR_NONE;