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)
74 retv_if(NULL == address, NULL);
76 for (l = paired_list; NULL != l; l = g_slist_next(l)) {
77 bt_remote_dev_info_t *rem_info = l->data;
82 if (!strncasecmp(rem_info->address, address, BT_ADDRESS_STRING_SIZE))
89 static void __bt_handle_pending_request(int result, int service_function)
93 invocation_info_t *req_info = NULL;
97 /* Get method invocation context */
98 for (l = _bt_get_invocation_list(); l != NULL; ) {
101 if (req_info == NULL || req_info->service_function != service_function)
104 switch (service_function) {
105 case BT_GET_BONDED_DEVICE: {
107 bt_remote_dev_info_t *rem_info;
108 bluetooth_device_info_t dev_info;
110 address = (char *)req_info->user_data;
112 BT_ERR_C("Unexpected: address is NULL");
116 BT_DBG("BT_GET_BONDED_DEVICE for [%s] found", address);
117 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
118 rem_info = _bt_service_get_remote_dev_info(address);
120 result = BLUETOOTH_ERROR_NONE;
121 _bt_copy_remote_device(rem_info, &dev_info);
122 g_array_append_vals(out_param, &dev_info,
123 sizeof(bluetooth_device_info_t));
125 BT_DBG("Device not found in paired list");
126 result = BLUETOOTH_ERROR_NOT_PAIRED;
129 _bt_service_method_return(req_info->context, out_param, result);
130 _bt_free_info_from_invocation_list(req_info);
131 g_array_free(out_param, TRUE);
134 case BT_GET_BONDED_DEVICES: {
135 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
136 _bt_service_get_bonded_dev_list(&out_param);
137 _bt_service_method_return(req_info->context, out_param, result);
138 _bt_free_info_from_invocation_list(req_info);
139 g_array_free(out_param, TRUE);
142 case BT_GET_IS_ALIAS_SET: {
144 bt_remote_dev_info_t *rem_info;
146 address = (char *)req_info->user_data;
148 BT_ERR_C("Unexpected: address is NULL");
152 BT_DBG("BT_GET_IS_ALIAS_SET for [%s] found", address);
153 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
154 rem_info = _bt_service_get_remote_dev_info(address);
156 result = BLUETOOTH_ERROR_NONE;
157 g_array_append_vals(out_param, &(rem_info->is_alias_set),
160 BT_DBG("Device not found in paired list");
161 result = BLUETOOTH_ERROR_NOT_PAIRED;
164 _bt_service_method_return(req_info->context, out_param, result);
165 _bt_free_info_from_invocation_list(req_info);
166 g_array_free(out_param, TRUE);
169 case BT_GET_CONNECTED_LINK_TYPE: {
171 bt_remote_dev_info_t *rem_info;
173 address = (char *)req_info->user_data;
175 BT_ERR_C("Unexpected: address is NULL");
179 BT_DBG("BT_GET_CONNECTED_LINK_TYPE for [%s] found", address);
180 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
181 rem_info = _bt_service_get_remote_dev_info(address);
183 result = BLUETOOTH_ERROR_NONE;
184 g_array_append_vals(out_param, &(rem_info->connected),
185 sizeof(bluetooth_connected_link_t));
187 else if (_bt_find_remote_gatt_client_info(address) || _bt_find_remote_gatt_server_info(address)) {
188 bluetooth_connected_link_t value = BLUETOOTH_CONNECTED_LINK_LE;
189 result = BLUETOOTH_ERROR_NONE;
190 g_array_append_vals(out_param, &(value),
191 sizeof(bluetooth_connected_link_t));
194 BT_DBG("Device not found in paired list \n Device not found in the LE devices list");
195 result = BLUETOOTH_ERROR_NOT_FOUND;
198 _bt_service_method_return(req_info->context, out_param, result);
199 _bt_free_info_from_invocation_list(req_info);
200 g_array_free(out_param, TRUE);
204 BT_ERR_C("Unknown service function %d", service_function);
209 static void __bt_service_fetch_dev_info_for_bonded_addr_list(void)
211 unsigned int count = g_slist_length(bonded_addr_list);
215 BT_INFO("bonded_list_index: %d", bonded_list_index);
216 for (; bonded_list_index < count; bonded_list_index++) {
217 GSList *l = g_slist_nth(bonded_addr_list, bonded_list_index);
218 bluetooth_device_address_t *dev_addr = l->data;
223 if (BLUETOOTH_ERROR_NONE != _bt_device_get_bonded_device_info(dev_addr)) {
224 char address[BT_ADDRESS_STRING_SIZE];
225 _bt_convert_addr_type_to_string(address, dev_addr->addr);
226 BT_ERR("_bt_device_get_bonded_device_info Failed for [%s]", address);
232 /* Retrieval of bonded device list completed */
233 bonded_list_index = 0;
234 bonded_list_retrieved = TRUE;
235 g_slist_free_full(bonded_addr_list, g_free);
236 bonded_addr_list = NULL;
238 /* Send reply if request for BT_GET_BONDED_DEVICES is pending */
239 __bt_handle_pending_request(
240 BLUETOOTH_ERROR_NONE, BT_GET_BONDED_DEVICES);
242 /* Send reply if request for BT_GET_BONDED_DEVICE is pending */
243 __bt_handle_pending_request(
244 BLUETOOTH_ERROR_NONE, BT_GET_BONDED_DEVICE);
246 __bt_handle_pending_request(
247 BLUETOOTH_ERROR_NONE, BT_GET_IS_ALIAS_SET);
248 __bt_handle_pending_request(
249 BLUETOOTH_ERROR_NONE, BT_GET_CONNECTED_LINK_TYPE);
253 static void __bt_update_connected_status(bt_remote_dev_info_t *rem_info, gboolean connected, unsigned char type)
259 switch (rem_info->connected) {
260 case BLUETOOTH_CONNECTED_LINK_NONE:
261 rem_info->connected = BLUETOOTH_CONNECTED_LINK_BREDR;
263 case BLUETOOTH_CONNECTED_LINK_LE:
264 rem_info->connected = BLUETOOTH_CONNECTED_LINK_BREDR_LE;
267 BT_ERR_C("rem_info->connected is already set to desired value: %d",
268 rem_info->connected);
271 switch (rem_info->connected) {
272 case BLUETOOTH_CONNECTED_LINK_NONE:
273 rem_info->connected = BLUETOOTH_CONNECTED_LINK_LE;
275 case BLUETOOTH_CONNECTED_LINK_BREDR:
276 rem_info->connected = BLUETOOTH_CONNECTED_LINK_BREDR_LE;
279 BT_ERR_C("rem_info->connected is already set to desired value: %d",
280 rem_info->connected);
285 switch (rem_info->connected) {
286 case BLUETOOTH_CONNECTED_LINK_BREDR:
287 rem_info->connected = BLUETOOTH_CONNECTED_LINK_NONE;
289 case BLUETOOTH_CONNECTED_LINK_BREDR_LE:
290 rem_info->connected = BLUETOOTH_CONNECTED_LINK_LE;
293 BT_ERR_C("rem_info->connected is already set to desired value: %d",
294 rem_info->connected);
297 switch (rem_info->connected) {
298 case BLUETOOTH_CONNECTED_LINK_LE:
299 rem_info->connected = BLUETOOTH_CONNECTED_LINK_NONE;
301 case BLUETOOTH_CONNECTED_LINK_BREDR_LE:
302 rem_info->connected = BLUETOOTH_CONNECTED_LINK_BREDR;
305 BT_ERR_C("rem_info->connected is already set to desired value: %d",
306 rem_info->connected);
314 void _bt_update_remote_dev_property(
315 const char *address, bt_device_prop_type_e type, void *value)
317 bt_remote_dev_info_t *rem_info;
319 BT_DBG("Property type: %d", type);
320 rem_info = _bt_service_get_remote_dev_info(address);
321 ret_if(NULL == rem_info);
324 case DEV_PROP_CONNECTED: {
325 bt_device_conn_info_t *conn_info = value;
327 __bt_update_connected_status(
328 rem_info, conn_info->connected, conn_info->type);
331 case DEV_PROP_NAME: {
334 if (name && strlen(name) > 0) {
335 g_free(rem_info->name);
336 rem_info->name = g_strdup(name);
340 case DEV_PROP_ALIAS: {
343 g_free(rem_info->alias);
344 rem_info->alias = NULL;
345 rem_info->is_alias_set = FALSE;
347 if (alias && strlen(alias) > 0) {
348 rem_info->alias = g_strdup(alias);
349 rem_info->is_alias_set = TRUE;
353 case DEV_PROP_TRUST: {
354 gboolean *trusted = value;
355 rem_info->trust = *trusted;
358 case DEV_PROP_SERVICES: {
359 bt_remote_dev_info_t *src = value;
361 if (src->uuid_count > 0 && src->uuids) {
364 /* Release previously allocated UUIDs */
365 if (rem_info->uuid_count > 0 && rem_info->uuids)
366 for (i = 0; i < rem_info->uuid_count; i++)
367 g_free(rem_info->uuids[i]);
368 g_free(rem_info->uuids);
370 /* Copy new UUID list */
371 rem_info->uuids = g_malloc0(src->uuid_count * sizeof(char *));
372 for (i = 0; i < src->uuid_count; i++)
373 rem_info->uuids[i] = g_strdup(src->uuids[i]);
375 rem_info->uuid_count = src->uuid_count;
376 BT_DBG("UUID count: %d", rem_info->uuid_count);
381 BT_DBG("Unknown property");
387 void _bt_service_add_device_to_bonded_list(bt_remote_dev_info_t *rem_info)
389 bt_remote_dev_info_t *dev_info;
391 ret_if(NULL == rem_info);
393 dev_info = _bt_service_get_remote_dev_info(rem_info->address);
395 BT_DBG("Device info not present, allocate memory");
396 dev_info = g_malloc0(sizeof(bt_remote_dev_info_t));
397 paired_list = g_slist_append(paired_list, dev_info);
400 _bt_copy_remote_dev_info(dev_info, rem_info);
402 if (!bonded_list_retrieved) {
403 char addr_str[BT_ADDRESS_STRING_SIZE];
404 bluetooth_device_address_t *dev_addr;
407 l = g_slist_nth(bonded_addr_list, bonded_list_index);
409 BT_ERR_C("l is NULL unexpectedly, need to check");
415 BT_ERR_C("dev_addr is NULL unexpectedly, need to check");
419 _bt_convert_addr_type_to_string(addr_str, dev_addr->addr);
420 if (!strncasecmp(addr_str, rem_info->address, BT_ADDRESS_STRING_SIZE)) {
422 __bt_service_fetch_dev_info_for_bonded_addr_list();
428 void _bt_service_remove_device_from_bonded_list(const char *address)
430 bt_remote_dev_info_t *rem_info;
433 ret_if(NULL == address);
435 rem_info = _bt_service_get_remote_dev_info(address);
437 BT_DBG("Device not found in list");
441 paired_list = g_slist_remove(paired_list, rem_info);
442 _bt_free_remote_dev(rem_info);
446 void _bt_device_handle_paired_address_list(bluetooth_device_address_t *addr_list, int count)
452 if (bonded_list_retrieved) {
453 BT_ERR_C("Unexpected bonded address list received");
458 BT_DBG("No paired device found");
459 bonded_list_index = 0;
460 bonded_list_retrieved = TRUE;
464 ret_if(NULL == addr_list);
466 for (indx = 0; indx < count; indx++) {
467 bluetooth_device_address_t *dev_addr;
469 dev_addr = g_memdup(&(addr_list[indx]), sizeof(bluetooth_device_address_t));
470 bonded_addr_list = g_slist_append(bonded_addr_list, dev_addr);
473 __bt_service_fetch_dev_info_for_bonded_addr_list();
477 static gboolean __check_bonded_devices(gpointer data)
481 retv_if(bonded_list_retrieved, FALSE);
483 /* Bonded devices are not yet retrived, retry */
484 if (BLUETOOTH_ERROR_NONE != _bt_adapter_get_bonded_devices())
485 BT_ERR_C("_bt_adapter_get_bonded_devices failed");
491 void _bt_device_handle_adapter_state(gboolean enabled)
496 BT_DBG("Adapter disabled");
497 g_slist_free_full(paired_list, _bt_free_paired_dev);
499 bonded_list_retrieved = FALSE;
503 if (BLUETOOTH_ERROR_NONE != _bt_adapter_get_bonded_devices())
504 BT_ERR_C("_bt_adapter_get_bonded_devices failed");
506 g_timeout_add_seconds(5, __check_bonded_devices, NULL);
510 static gboolean __reply_pending_request(gpointer data)
514 BT_INFO("Request: %d", *request);
515 __bt_handle_pending_request(BLUETOOTH_ERROR_NONE, *request);
520 int _bt_get_bonded_device_info(bluetooth_device_address_t *dev_addr)
522 char address[BT_ADDRESS_STRING_SIZE];
523 bt_remote_dev_info_t *rem_info;
524 int request = BT_GET_BONDED_DEVICE;
528 retv_if(!dev_addr, BLUETOOTH_ERROR_INVALID_PARAM);
530 if (!bonded_list_retrieved) {
532 * Blonded list retrival is in progress, return BLUETOOTH_ERROR_NONE here.
533 * reply will be sent once bonded list is retrieved completely.
535 return BLUETOOTH_ERROR_NONE;
538 _bt_convert_addr_type_to_string(address, dev_addr->addr);
540 rem_info = _bt_service_get_remote_dev_info(address);
542 BT_ERR("Bonded device not found in the list, return error");
543 return BLUETOOTH_ERROR_NOT_PAIRED;
546 g_idle_add(__reply_pending_request, g_memdup(&request, sizeof(int)));
548 return BLUETOOTH_ERROR_NONE;
551 int _bt_get_bonded_devices(void)
553 int request = BT_GET_BONDED_DEVICES;
556 if (!bonded_list_retrieved) {
558 * Blonded list retrival is in progress, return BLUETOOTH_ERROR_NONE here.
559 * reply will be sent once bonded list is retrieved completely.
561 return BLUETOOTH_ERROR_NONE;
564 g_idle_add(__reply_pending_request, g_memdup(&request, sizeof(int)));
566 return BLUETOOTH_ERROR_NONE;
569 int _bt_is_alias_set(bluetooth_device_address_t *device_address)
571 char address[BT_ADDRESS_STRING_SIZE];
572 bt_remote_dev_info_t *rem_info;
573 int request = BT_GET_IS_ALIAS_SET;
576 if (!bonded_list_retrieved) {
578 * Blonded list retrival is in progress, return BLUETOOTH_ERROR_NONE here.
579 * reply will be sent once bonded list is retrieved completely.
581 return BLUETOOTH_ERROR_NONE;
584 _bt_convert_addr_type_to_string(address, device_address->addr);
585 rem_info = _bt_service_get_remote_dev_info(address);
587 BT_ERR("Bonded device not found in the list, return error");
588 return BLUETOOTH_ERROR_NOT_PAIRED;
591 g_idle_add(__reply_pending_request, g_memdup(&request, sizeof(int)));
593 return BLUETOOTH_ERROR_NONE;
596 int _bt_get_connected_link(bluetooth_device_address_t *device_address)
598 int request = BT_GET_CONNECTED_LINK_TYPE;
601 if (!bonded_list_retrieved) {
603 * Blonded list retrival is in progress, return BLUETOOTH_ERROR_NONE here.
604 * reply will be sent once bonded list is retrieved completely.
606 return BLUETOOTH_ERROR_NONE;
609 g_idle_add(__reply_pending_request, g_memdup(&request, sizeof(int)));
611 return BLUETOOTH_ERROR_NONE;
614 gboolean _bt_is_bonded_devices_retrived(void)
616 return bonded_list_retrieved;