2 * Copyright (c) 2015 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Atul Rai <a.rai@samsung.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
26 /*bt-service headers */
27 #include "bt-internal-types.h"
28 #include "bt-service-common.h"
29 #include "bt-service-util.h"
30 #include "bt-service-event-receiver.h"
31 #include "bt-request-handler.h"
32 #include "bt-service-event.h"
33 #include "bt-service-core-adapter.h"
34 #include "bt-service-core-device.h"
35 #include "bt-service-device-internal.h"
36 #include "bt-service-gatt.h"
39 #include <oal-event.h>
40 #include <oal-manager.h>
42 static GSList *paired_list;
43 static GSList *bonded_addr_list;
44 static unsigned int bonded_list_index = 0;
45 static gboolean bonded_list_retrieved = FALSE;
47 void _bt_service_get_bonded_dev_list(GArray **dev_list)
53 ret_if(NULL == dev_list);
55 for (l = paired_list; NULL != l; l = g_slist_next(l)) {
56 bt_remote_dev_info_t *rem_info = l->data;
57 bluetooth_device_info_t dev_info;
62 _bt_copy_remote_device(rem_info, &dev_info);
63 g_array_append_vals(*dev_list, &dev_info, sizeof(bluetooth_device_info_t));
70 bt_remote_dev_info_t *_bt_service_get_remote_dev_info(const char *address)
75 retv_if(NULL == address, NULL);
77 for (l = paired_list; NULL != l; l = g_slist_next(l)) {
78 bt_remote_dev_info_t *rem_info = l->data;
83 if (!strncasecmp(rem_info->address, address, BT_ADDRESS_STRING_SIZE)) {
84 BT_DBG("Device found");
93 static void __bt_handle_pending_request(int result, int service_function)
97 invocation_info_t *req_info = NULL;
101 /* Get method invocation context */
102 for (l = _bt_get_invocation_list(); l != NULL; ) {
105 if (req_info == NULL || req_info->service_function != service_function)
108 switch (service_function) {
109 case BT_GET_BONDED_DEVICE: {
111 bt_remote_dev_info_t *rem_info;
112 bluetooth_device_info_t dev_info;
114 address = (char *)req_info->user_data;
116 BT_ERR_C("Unexpected: address is NULL");
120 BT_DBG("BT_GET_BONDED_DEVICE for [%s] found", address);
121 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
122 rem_info = _bt_service_get_remote_dev_info(address);
124 result = BLUETOOTH_ERROR_NONE;
125 _bt_copy_remote_device(rem_info, &dev_info);
126 g_array_append_vals(out_param, &dev_info,
127 sizeof(bluetooth_device_info_t));
129 BT_DBG("Device not found in paired list");
130 result = BLUETOOTH_ERROR_NOT_PAIRED;
133 _bt_service_method_return(req_info->context, out_param, result);
134 _bt_free_info_from_invocation_list(req_info);
135 g_array_free(out_param, TRUE);
138 case BT_GET_BONDED_DEVICES: {
139 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
140 _bt_service_get_bonded_dev_list(&out_param);
141 _bt_service_method_return(req_info->context, out_param, result);
142 _bt_free_info_from_invocation_list(req_info);
143 g_array_free(out_param, TRUE);
146 case BT_GET_IS_ALIAS_SET: {
148 bt_remote_dev_info_t *rem_info;
150 address = (char *)req_info->user_data;
152 BT_ERR_C("Unexpected: address is NULL");
156 BT_DBG("BT_GET_IS_ALIAS_SET for [%s] found", address);
157 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
158 rem_info = _bt_service_get_remote_dev_info(address);
160 result = BLUETOOTH_ERROR_NONE;
161 g_array_append_vals(out_param, &(rem_info->is_alias_set),
164 BT_DBG("Device not found in paired list");
165 result = BLUETOOTH_ERROR_NOT_PAIRED;
168 _bt_service_method_return(req_info->context, out_param, result);
169 _bt_free_info_from_invocation_list(req_info);
170 g_array_free(out_param, TRUE);
173 case BT_GET_CONNECTED_LINK_TYPE: {
175 bt_remote_dev_info_t *rem_info;
177 address = (char *)req_info->user_data;
179 BT_ERR_C("Unexpected: address is NULL");
183 BT_DBG("BT_GET_CONNECTED_LINK_TYPE for [%s] found", address);
184 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
185 rem_info = _bt_service_get_remote_dev_info(address);
187 result = BLUETOOTH_ERROR_NONE;
188 g_array_append_vals(out_param, &(rem_info->connected),
189 sizeof(bluetooth_connected_link_t));
191 else if (_bt_find_remote_gatt_client_info(address) || _bt_find_remote_gatt_server_info(address)) {
192 bluetooth_connected_link_t value = BLUETOOTH_CONNECTED_LINK_LE;
193 result = BLUETOOTH_ERROR_NONE;
194 g_array_append_vals(out_param, &(value),
195 sizeof(bluetooth_connected_link_t));
198 BT_DBG("Device not found in paired list \n Device not found in the LE devices list");
199 result = BLUETOOTH_ERROR_NOT_FOUND;
202 _bt_service_method_return(req_info->context, out_param, result);
203 _bt_free_info_from_invocation_list(req_info);
204 g_array_free(out_param, TRUE);
208 BT_ERR_C("Unknown service function %d", service_function);
213 static void __bt_service_fetch_dev_info_for_bonded_addr_list(void)
215 unsigned int count = g_slist_length(bonded_addr_list);
219 BT_INFO("bonded_list_index: %d", bonded_list_index);
220 for (; bonded_list_index < count; bonded_list_index++) {
221 GSList *l = g_slist_nth(bonded_addr_list, bonded_list_index);
222 bluetooth_device_address_t *dev_addr = l->data;
227 if (BLUETOOTH_ERROR_NONE != _bt_device_get_bonded_device_info(dev_addr)) {
228 char address[BT_ADDRESS_STRING_SIZE];
229 _bt_convert_addr_type_to_string(address, dev_addr->addr);
230 BT_ERR("_bt_device_get_bonded_device_info Failed for [%s]", address);
236 /* Retrieval of bonded device list completed */
237 bonded_list_index = 0;
238 bonded_list_retrieved = TRUE;
239 g_slist_free_full(bonded_addr_list, g_free);
240 bonded_addr_list = NULL;
242 /* Send reply if request for BT_GET_BONDED_DEVICES is pending */
243 __bt_handle_pending_request(
244 BLUETOOTH_ERROR_NONE, BT_GET_BONDED_DEVICES);
246 /* Send reply if request for BT_GET_BONDED_DEVICE is pending */
247 __bt_handle_pending_request(
248 BLUETOOTH_ERROR_NONE, BT_GET_BONDED_DEVICE);
250 __bt_handle_pending_request(
251 BLUETOOTH_ERROR_NONE, BT_GET_IS_ALIAS_SET);
252 __bt_handle_pending_request(
253 BLUETOOTH_ERROR_NONE, BT_GET_CONNECTED_LINK_TYPE);
257 static void __bt_update_connected_status(bt_remote_dev_info_t *rem_info, gboolean connected, unsigned char type)
263 switch (rem_info->connected) {
264 case BLUETOOTH_CONNECTED_LINK_NONE:
265 rem_info->connected = BLUETOOTH_CONNECTED_LINK_BREDR;
267 case BLUETOOTH_CONNECTED_LINK_LE:
268 rem_info->connected = BLUETOOTH_CONNECTED_LINK_BREDR_LE;
271 BT_ERR_C("rem_info->connected is already set to desired value: %d",
272 rem_info->connected);
275 switch (rem_info->connected) {
276 case BLUETOOTH_CONNECTED_LINK_NONE:
277 rem_info->connected = BLUETOOTH_CONNECTED_LINK_LE;
279 case BLUETOOTH_CONNECTED_LINK_BREDR:
280 rem_info->connected = BLUETOOTH_CONNECTED_LINK_BREDR_LE;
283 BT_ERR_C("rem_info->connected is already set to desired value: %d",
284 rem_info->connected);
289 switch (rem_info->connected) {
290 case BLUETOOTH_CONNECTED_LINK_BREDR:
291 rem_info->connected = BLUETOOTH_CONNECTED_LINK_NONE;
293 case BLUETOOTH_CONNECTED_LINK_BREDR_LE:
294 rem_info->connected = BLUETOOTH_CONNECTED_LINK_LE;
297 BT_ERR_C("rem_info->connected is already set to desired value: %d",
298 rem_info->connected);
301 switch (rem_info->connected) {
302 case BLUETOOTH_CONNECTED_LINK_LE:
303 rem_info->connected = BLUETOOTH_CONNECTED_LINK_NONE;
305 case BLUETOOTH_CONNECTED_LINK_BREDR_LE:
306 rem_info->connected = BLUETOOTH_CONNECTED_LINK_BREDR;
309 BT_ERR_C("rem_info->connected is already set to desired value: %d",
310 rem_info->connected);
318 void _bt_update_remote_dev_property(
319 const char *address, bt_device_prop_type_e type, void *value)
321 bt_remote_dev_info_t *rem_info;
325 BT_DBG("Property type: %d", type);
326 rem_info = _bt_service_get_remote_dev_info(address);
327 ret_if(NULL == rem_info);
330 case DEV_PROP_CONNECTED: {
331 bt_device_conn_info_t *conn_info = value;
333 __bt_update_connected_status(
334 rem_info, conn_info->connected, conn_info->type);
337 case DEV_PROP_NAME: {
340 if (name && strlen(name) > 0) {
341 g_free(rem_info->name);
342 rem_info->name = g_strdup(name);
346 case DEV_PROP_ALIAS: {
349 g_free(rem_info->alias);
350 rem_info->alias = NULL;
351 rem_info->is_alias_set = FALSE;
353 if (alias && strlen(alias) > 0) {
354 rem_info->alias = g_strdup(alias);
355 rem_info->is_alias_set = TRUE;
359 case DEV_PROP_TRUST: {
360 gboolean *trusted = value;
361 rem_info->trust = *trusted;
364 case DEV_PROP_SERVICES: {
365 bt_remote_dev_info_t *src = value;
367 if (src->uuid_count > 0 && src->uuids) {
370 /* Release previously allocated UUIDs */
371 if (rem_info->uuid_count > 0 && rem_info->uuids)
372 for (i = 0; i < rem_info->uuid_count; i++)
373 g_free(rem_info->uuids[i]);
374 g_free(rem_info->uuids);
376 /* Copy new UUID list */
377 rem_info->uuids = g_malloc0(src->uuid_count * sizeof(char *));
378 for (i = 0; i < src->uuid_count; i++)
379 rem_info->uuids[i] = g_strdup(src->uuids[i]);
381 rem_info->uuid_count = src->uuid_count;
382 BT_DBG("UUID count: %d", rem_info->uuid_count);
387 BT_DBG("Unknown property");
394 void _bt_service_add_device_to_bonded_list(bt_remote_dev_info_t *rem_info)
396 bt_remote_dev_info_t *dev_info;
399 ret_if(NULL == rem_info);
401 dev_info = _bt_service_get_remote_dev_info(rem_info->address);
403 BT_DBG("Device info not present, allocate memory");
404 dev_info = g_malloc0(sizeof(bt_remote_dev_info_t));
405 paired_list = g_slist_append(paired_list, dev_info);
408 _bt_copy_remote_dev_info(dev_info, rem_info);
410 if (!bonded_list_retrieved) {
411 char addr_str[BT_ADDRESS_STRING_SIZE];
412 bluetooth_device_address_t *dev_addr;
415 l = g_slist_nth(bonded_addr_list, bonded_list_index);
417 BT_ERR_C("l is NULL unexpectedly, need to check");
423 BT_ERR_C("dev_addr is NULL unexpectedly, need to check");
427 _bt_convert_addr_type_to_string(addr_str, dev_addr->addr);
428 if (!strncasecmp(addr_str, rem_info->address, BT_ADDRESS_STRING_SIZE)) {
430 __bt_service_fetch_dev_info_for_bonded_addr_list();
437 void _bt_service_remove_device_from_bonded_list(const char *address)
439 bt_remote_dev_info_t *rem_info;
442 ret_if(NULL == address);
444 rem_info = _bt_service_get_remote_dev_info(address);
446 BT_DBG("Device not found in list");
450 paired_list = g_slist_remove(paired_list, rem_info);
451 _bt_free_remote_dev(rem_info);
455 void _bt_device_handle_paired_address_list(bluetooth_device_address_t *addr_list, int count)
461 if (bonded_list_retrieved) {
462 BT_ERR_C("Unexpected bonded address list received");
467 BT_DBG("No paired device found");
468 bonded_list_index = 0;
469 bonded_list_retrieved = TRUE;
473 ret_if(NULL == addr_list);
475 for (indx = 0; indx < count; indx++) {
476 bluetooth_device_address_t *dev_addr;
478 dev_addr = g_memdup(&(addr_list[indx]), sizeof(bluetooth_device_address_t));
479 bonded_addr_list = g_slist_append(bonded_addr_list, dev_addr);
482 __bt_service_fetch_dev_info_for_bonded_addr_list();
486 static gboolean __check_bonded_devices(gpointer data)
490 retv_if(bonded_list_retrieved, FALSE);
492 /* Bonded devices are not yet retrived, retry */
493 if (BLUETOOTH_ERROR_NONE != _bt_adapter_get_bonded_devices())
494 BT_ERR_C("_bt_adapter_get_bonded_devices failed");
500 void _bt_device_handle_adapter_state(gboolean enabled)
505 BT_DBG("Adapter disabled");
506 g_slist_free_full(paired_list, g_free);
508 bonded_list_retrieved = FALSE;
512 if (BLUETOOTH_ERROR_NONE != _bt_adapter_get_bonded_devices())
513 BT_ERR_C("_bt_adapter_get_bonded_devices failed");
515 g_timeout_add_seconds(5, __check_bonded_devices, NULL);
519 static gboolean __reply_pending_request(gpointer data)
523 BT_INFO("Request: %d", *request);
524 __bt_handle_pending_request(BLUETOOTH_ERROR_NONE, *request);
529 int _bt_get_bonded_device_info(bluetooth_device_address_t *dev_addr)
531 char address[BT_ADDRESS_STRING_SIZE];
532 bt_remote_dev_info_t *rem_info;
533 int request = BT_GET_BONDED_DEVICE;
537 retv_if(!dev_addr, BLUETOOTH_ERROR_INVALID_PARAM);
539 if (!bonded_list_retrieved) {
541 * Blonded list retrival is in progress, return BLUETOOTH_ERROR_NONE here.
542 * reply will be sent once bonded list is retrieved completely.
544 return BLUETOOTH_ERROR_NONE;
547 _bt_convert_addr_type_to_string(address, dev_addr->addr);
549 rem_info = _bt_service_get_remote_dev_info(address);
551 BT_ERR("Bonded device not found in the list, return error");
552 return BLUETOOTH_ERROR_NOT_PAIRED;
555 g_idle_add(__reply_pending_request, g_memdup(&request, sizeof(int)));
557 return BLUETOOTH_ERROR_NONE;
560 int _bt_get_bonded_devices(void)
562 int request = BT_GET_BONDED_DEVICES;
565 if (!bonded_list_retrieved) {
567 * Blonded list retrival is in progress, return BLUETOOTH_ERROR_NONE here.
568 * reply will be sent once bonded list is retrieved completely.
570 return BLUETOOTH_ERROR_NONE;
573 g_idle_add(__reply_pending_request, g_memdup(&request, sizeof(int)));
575 return BLUETOOTH_ERROR_NONE;
578 int _bt_is_alias_set(bluetooth_device_address_t *device_address)
580 char address[BT_ADDRESS_STRING_SIZE];
581 bt_remote_dev_info_t *rem_info;
582 int request = BT_GET_IS_ALIAS_SET;
585 if (!bonded_list_retrieved) {
587 * Blonded list retrival is in progress, return BLUETOOTH_ERROR_NONE here.
588 * reply will be sent once bonded list is retrieved completely.
590 return BLUETOOTH_ERROR_NONE;
593 _bt_convert_addr_type_to_string(address, device_address->addr);
594 rem_info = _bt_service_get_remote_dev_info(address);
596 BT_ERR("Bonded device not found in the list, return error");
597 return BLUETOOTH_ERROR_NOT_PAIRED;
600 g_idle_add(__reply_pending_request, g_memdup(&request, sizeof(int)));
602 return BLUETOOTH_ERROR_NONE;
605 int _bt_get_connected_link(bluetooth_device_address_t *device_address)
607 int request = BT_GET_CONNECTED_LINK_TYPE;
610 if (!bonded_list_retrieved) {
612 * Blonded list retrival is in progress, return BLUETOOTH_ERROR_NONE here.
613 * reply will be sent once bonded list is retrieved completely.
615 return BLUETOOTH_ERROR_NONE;
618 g_idle_add(__reply_pending_request, g_memdup(&request, sizeof(int)));
620 return BLUETOOTH_ERROR_NONE;
623 gboolean _bt_is_bonded_devices_retrived(void)
625 return bonded_list_retrieved;