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 <syspopup_caller.h>
24 #include <bundle_internal.h>
26 #include "bluetooth-api.h"
27 #include "bt-internal-types.h"
29 #include "bt-service-common.h"
30 #include "bt-service-adapter-le.h"
31 #include "bt-service-event.h"
32 #include "bt-service-adapter.h"
33 #include "bt-service-util.h"
34 #include "bt-service-tds.h"
36 #define GATT_SERV_INTERFACE "org.bluez.GattService1"
37 #define GATT_CHAR_INTERFACE "org.bluez.GattCharacteristic1"
38 #define GATT_DESC_INTERFACE "org.bluez.GattDescriptor1"
40 #define GATT_DEFAULT_TIMEOUT (6 * 1000) /* Dependent on supervision timeout 6 sec */
41 #define BT_MAX_DBUS_SENDER_PATH 100
42 #define BT_TRANSPORT_ACTIVATION_TIMEOUT_MAX 15000 /* Timeout for Indication from Provider in msec */
44 #define TDS_CONTROL_POINT_RESPONSE_SUCCESS 0x00
45 #define TDS_CONTROL_POINT_RESPONSE_OP_CODE_NOT_SUPPORTED 0x01
46 #define TDS_CONTROL_POINT_RESPONSE_INVALID_PARAMETER 0x02
47 #define TDS_CONTROL_POINT_RESPONSE_UNSUPPORTED_ORG_ID 0x03
48 #define TDS_CONTROL_POINT_RESPONSE_OPERATION_FAILED 0x04
50 #define BT_ADV_FLAG_LEN 3
51 #define TDS_DATA_LEN_MAX 1024
52 #define NUM_TDS_PROVIDER_MAX 10
55 BT_AD_TYPE_LOCAL_NAME = 0x09, /**<Complete local name */
56 BT_AD_TYPE_COD = 0x0D, /**< Class of Device */
57 BT_AD_TYPE_MANUF_DATA = 0xFF, /**< Manufacturer data */
58 } bt_advertising_ad_type_e;
61 TDS_ROLE_UNSPECIFIED = 0,
64 TDS_ROLE_SEEKER_PROVIDER
68 TRANSPORT_DATA_COMPLETE,
69 TRANSPORT_DATA_INCOMPLETE
70 } bt_tds_transport_data_state_t;
73 unsigned int tds_handle;
75 bluetooth_tds_transport_t transport;
76 bluetooth_tds_transport_state_t state;
77 unsigned int data_len;
79 } bt_tds_transport_info_t;
84 unsigned int manuf_data_len;
85 unsigned char *manuf_data;
89 /* TDS Activation Request structure */
93 unsigned int activation_timeout_id;
95 } bt_tds_activation_info;
97 /* TDS transport specific data read Request info structure */
102 } bt_tds_data_read_req_info;
104 GSList *provider_list = NULL;
105 static int assigned_adv_handle;
106 static gboolean adv_handle_used[NUM_TDS_PROVIDER_MAX];
108 #define TDS_MANUF_DATA_LEN_MAX 29
109 static unsigned char manuf_data[TDS_MANUF_DATA_LEN_MAX];
110 static int manuf_data_len;
112 static GSList *tds_activation_info_list = NULL;
113 static GSList *tds_data_read_req_info_list = NULL;
115 /* Forward declarations */
116 static bt_tds_activation_info* __bt_tds_activation_info_by_address(char *address);
117 static bt_tds_data_read_req_info* __bt_tds_data_read_info_by_address(char *address);
118 static void __bt_tds_send_indication_event(bt_tds_activation_info *info, unsigned char *buffer, int len);
119 static void __bt_tds_remove_indication_info(bt_tds_activation_info *info);
120 static void __bt_tds_remove_data_read_req_info(bt_tds_data_read_req_info *info);
122 static void __bt_init_adv_handle(void)
124 assigned_adv_handle = 0;
125 memset(adv_handle_used, 0x00, NUM_TDS_PROVIDER_MAX);
128 static int __bt_provider_get_adv_handle(void)
132 index = assigned_adv_handle + 1;
134 if (index >= NUM_TDS_PROVIDER_MAX)
137 while (adv_handle_used[index] == TRUE) {
138 if (index == assigned_adv_handle) {
139 /* No available ID */
140 BT_ERR("All adv_handles are used");
146 if (index >= NUM_TDS_PROVIDER_MAX)
150 assigned_adv_handle = index;
151 adv_handle_used[index] = TRUE;
153 return assigned_adv_handle;
156 static void __bt_provider_delete_adv_handle(int handle)
158 ret_if(handle >= NUM_TDS_PROVIDER_MAX);
161 adv_handle_used[handle] = FALSE;
164 static unsigned char __bt_tds_get_organization_id(int transport)
166 BT_INFO("transport: %d", transport);
169 case BLUETOOTH_TDS_TRANSPORT_BT:
171 case BLUETOOTH_TDS_TRANSPORT_CUSTOM:
174 BT_ERR("Invaid transport");
179 static int __bt_tds_get_transport(unsigned char org_id)
181 BT_INFO("org_id: %d", org_id);
185 return BLUETOOTH_TDS_TRANSPORT_BT;
187 return BLUETOOTH_TDS_TRANSPORT_CUSTOM;
189 BT_ERR("Invaid org_id");
190 return BLUETOOTH_TDS_TRANSPORT_INVALID;
194 static unsigned char __bt_tds_set_role(unsigned char flag, bt_tds_role_t role)
197 BT_INFO("Flag: %.2X, Role: %d", flag, role);
200 case TDS_ROLE_UNSPECIFIED:
203 case TDS_ROLE_SEEKER:
207 case TDS_ROLE_PROVIDER:
211 case TDS_ROLE_SEEKER_PROVIDER:
216 BT_ERR("Invalid role received");
222 static int __bt_tds_get_role(unsigned char flag)
225 BT_INFO("Flag: %.2X", flag);
227 if (0x03 == (flag & 0x03))
228 return TDS_ROLE_SEEKER_PROVIDER;
229 else if (0x02 == (flag & 0x02))
230 return TDS_ROLE_PROVIDER;
231 else if (0x01 == (flag & 0x01))
232 return TDS_ROLE_SEEKER;
234 return TDS_ROLE_UNSPECIFIED;
237 static unsigned char __bt_tds_set_transport_data_incomplete(
238 unsigned char flag, gboolean state)
240 BT_INFO("Flag: %.2X, Data state: %d", flag, state);
243 flag = flag | 0x04; /* Set incomplete bit to 1 */
245 flag = flag & 0xFB; /* Set incomplete bit to 0 */
250 static unsigned char __bt_tds_set_transport_state(
251 unsigned char flag, bluetooth_tds_transport_state_t state)
253 BT_INFO("Flag: %.2X, Transport state: %d", flag, state);
256 case BLUETOOTH_TDS_TRANSPORT_STATE_OFF:
259 case BLUETOOTH_TDS_TRANSPORT_STATE_ON:
263 case BLUETOOTH_TDS_TRANSPORT_STATE_UNAVAILABLE:
267 case BLUETOOTH_TDS_TRANSPORT_STATE_RESERVED:
272 BT_ERR("Invalid transport state received");
278 static unsigned char __bt_tds_get_activation_response_code(int result)
283 case BLUETOOTH_ERROR_NONE:
284 resp = TDS_CONTROL_POINT_RESPONSE_SUCCESS; /* Success */
286 case BLUETOOTH_ERROR_INVALID_PARAM:
287 resp = TDS_CONTROL_POINT_RESPONSE_INVALID_PARAMETER; /*Invalid Parameter */
289 case BLUETOOTH_ERROR_NOT_SUPPORT:
290 resp = TDS_CONTROL_POINT_RESPONSE_UNSUPPORTED_ORG_ID; /* Unsupported Organization ID*/
292 case BLUETOOTH_ERROR_INTERNAL:
293 resp = TDS_CONTROL_POINT_RESPONSE_OPERATION_FAILED; /* */
296 BT_INFO("Unknown response code: %d received", result);
297 resp = TDS_CONTROL_POINT_RESPONSE_OPERATION_FAILED;
303 static bt_tds_provider_t* __bt_tds_provider_find_from_list(const char *sender)
307 retv_if(NULL == sender, NULL);
309 for (l = provider_list; l != NULL; l = g_slist_next(l)) {
310 bt_tds_provider_t *provider = l->data;
311 if (provider && (g_strcmp0(provider->sender, sender) == 0))
318 static unsigned char* __bt_tds_provider_get_tds_blocks(unsigned int *length)
322 unsigned int len = 0;
323 unsigned char data[TDS_DATA_LEN_MAX];
325 retv_if(NULL == length, NULL);
327 for (l = provider_list; NULL != l; l = g_slist_next(l)) {
328 bt_tds_provider_t *provider = l->data;
333 for (l1 = provider->transports; l1 != NULL; l1 = g_slist_next(l1)) {
334 bt_tds_transport_info_t *transport_info = l1->data;
336 if (!transport_info || !transport_info->data)
339 if (len + transport_info->data_len > sizeof(data)) {
340 BT_ERR("Could not set complete the tds data, size exceeded");
344 memcpy(&(data[len]), transport_info->data, transport_info->data_len);
345 len += transport_info->data_len;
350 BT_INFO("length = %d", *length);
351 return g_memdup(data, *length);
354 static void __bt_tds_set_scan_resp_data(bt_tds_provider_t *provider)
356 bluetooth_scan_resp_data_t scan_resp;
357 char *name = "bt-service";
365 name = provider->sender;
366 adv_handle = provider->adv_handle;
368 if (provider->manuf_data_len > 0) {
369 scan_resp.data[len++] = provider->manuf_data_len + 1;
370 scan_resp.data[len++] = BT_AD_TYPE_MANUF_DATA;
371 memcpy(&(scan_resp.data[len]), provider->manuf_data, provider->manuf_data_len);
372 len += provider->manuf_data_len;
375 if (manuf_data_len > 0) {
376 scan_resp.data[len++] = manuf_data_len + 1;
377 scan_resp.data[len++] = BT_AD_TYPE_MANUF_DATA;
378 memcpy(&(scan_resp.data[len]), manuf_data, manuf_data_len);
379 len += manuf_data_len;
383 if (len <= (BLUETOOTH_SCAN_RESP_DATA_LENGTH_MAX - 2)) {
385 scan_resp.data[len++] = 1;
386 scan_resp.data[len++] = BT_AD_TYPE_LOCAL_NAME;
389 ret = _bt_set_scan_response_data(name, adv_handle, &scan_resp, len, FALSE);
390 if (ret != BLUETOOTH_ERROR_NONE)
391 BT_ERR("Failed to set_scan response data with error: %d", ret);
397 * Multi adv not supported (Lagacy device/chip) then, and it is difficult to add all the
398 * tds block in single adv pkt. So for each supported orgId, add only 1 tds blocks with
399 * incomplte tds flag bit set, in adv data.
401 static int __bt_tds_provider_get_tds_adv_data(bt_tds_provider_t *provider, guint8 *adv_data)
405 unsigned int len = 0;
406 unsigned int max_adv_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - BT_ADV_FLAG_LEN;
409 retv_if(NULL == provider, -1);
410 retv_if(NULL == adv_data, -1);
415 for (transport = BLUETOOTH_TDS_TRANSPORT_BT;
416 transport < BLUETOOTH_TDS_TRANSPORT_INVALID; transport++) {
417 gboolean flag = FALSE;
419 if (len > max_adv_len - 3)
422 for (l = provider_list; l != NULL; l = g_slist_next(l)) {
423 bt_tds_provider_t *provider = l->data;
428 for (l1 = provider->transports; l1 != NULL; l1 = g_slist_next(l1)) {
429 bt_tds_transport_info_t *transport_info = l1->data;
431 if (!transport_info || !transport_info->data ||
432 transport_info->transport != transport)
435 adv_data[len++] = transport_info->data[0]; /* Organization Id */
436 adv_data[len++] = __bt_tds_set_transport_data_incomplete(
437 transport_info->data[1], TRUE);
438 adv_data[len++] = 0; /* Set Transport data len = 0 */
448 BT_INFO("len = %d", len);
450 return -1; /* No data */
452 adv_data[0] = len - 1;
456 /* If multi adv supported set each provider's data in seperate adv slot */
457 static int __bt_tds_provider_get_tds_multi_adv_data(bt_tds_provider_t *provider, guint8 *adv_data)
460 unsigned int len = 0;
461 unsigned int max_adv_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - BT_ADV_FLAG_LEN;
464 retv_if(NULL == provider, -1);
465 retv_if(NULL == adv_data, -1);
467 count = g_slist_length(provider->transports);
471 for (l = provider->transports; l != NULL; l = g_slist_next(l)) {
472 bt_tds_transport_info_t *transport_info = l->data;
474 if (!transport_info || !transport_info->data)
477 if ((len + transport_info->data_len < max_adv_len - 3) ||
478 (count <= 1 && (len + transport_info->data_len < max_adv_len))) {
479 memcpy(&(adv_data[len]), transport_info->data, transport_info->data_len);
480 len += transport_info->data_len;
482 /* Not able to accomodated complete data in adv pkt */
483 adv_data[len++] = transport_info->data[0]; /* Organization Id */
484 adv_data[len++] = __bt_tds_set_transport_data_incomplete(
485 transport_info->data[1], TRUE);
486 adv_data[len++] = 0; /* Set Transport data len = 0 */
493 BT_INFO("len = %d", len);
495 return -1; /* No data */
497 adv_data[0] = len - 1;
501 static int __bt_tds_set_advertising(bt_tds_provider_t *provider)
503 bluetooth_advertising_data_t adv;
504 bluetooth_advertising_params_t param;
505 char *name = "bt-service";
514 name = provider->sender;
515 adv_handle = provider->adv_handle;
517 /* Get updated TDS advertising data */
518 length = __bt_tds_provider_get_tds_multi_adv_data(provider, adv.data);
520 BT_INFO("No adv data found, return");
522 /* No provider is present, no need to enable advertising */
523 if (0 == g_slist_length(provider_list))
524 return BLUETOOTH_ERROR_NONE;
526 /* Get updated TDS advertising data */
527 length = __bt_tds_provider_get_tds_adv_data(provider, adv.data);
529 BT_INFO("No adv data found, return");
532 /* If length <= 0, no need to start advertisement */
534 return BLUETOOTH_ERROR_NONE;
536 for (i = 0; i < length; i++)
537 BT_DBG("adv_data: %.2X", adv.data[i]);
539 ret = _bt_set_advertising_data(name, adv_handle, &adv, length, FALSE);
540 if (ret != BLUETOOTH_ERROR_NONE) {
541 BT_ERR("Failed to set ADV %d", ret);
545 /* set scan response data */
546 __bt_tds_set_scan_resp_data(provider);
548 param.interval_min = 500;
549 param.interval_max = 500;
550 param.filter_policy = BLUETOOTH_ALLOW_SCAN_CONN_ALL;
551 param.type = BLUETOOTH_ADV_CONNECTABLE;
553 ret = _bt_set_custom_advertising(name, adv_handle, TRUE, ¶m, FALSE);
554 if (ret != BLUETOOTH_ERROR_NONE) {
555 BT_ERR("Failed to enable advertising with error: %d", ret);
560 return BLUETOOTH_ERROR_NONE;
563 static int __bt_tds_disable_advertising(bt_tds_provider_t *provider)
565 char *name = "bt-service";
572 name = provider->sender;
573 adv_handle = provider->adv_handle;
576 /* First try to disable adv in case already advertising */
577 ret = _bt_set_advertising(name, adv_handle, FALSE, FALSE);
578 if (ret != BLUETOOTH_ERROR_NONE) {
579 BT_ERR("Failed to disable advertising with error: %d", ret);
580 ret = __bt_tds_set_advertising(provider);
581 if (ret != BLUETOOTH_ERROR_NONE) {
582 BT_ERR("Failed to enable advertising with error: %d", ret);
588 return BLUETOOTH_ERROR_NONE;
591 static int __bt_tds_provider_update_transport_data(bt_tds_provider_t *provider)
594 GDBusConnection *conn;
595 char *adapter_path = NULL;
596 GError *error = NULL;
597 GVariant *result = NULL;
598 GVariantBuilder *builder;
600 unsigned char *buf = NULL;
601 unsigned int length = 0;
606 conn = _bt_gdbus_get_system_gconn();
607 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
609 adapter_path = _bt_get_adapter_path();
610 if (adapter_path == NULL) {
611 BT_ERR("Could not get adapter path\n");
612 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
615 BT_INFO("Adapter path [%s]", adapter_path);
616 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
617 NULL, BT_BLUEZ_NAME, adapter_path,
618 BT_TDS_PROVIDER_INTERFACE, NULL, NULL);
619 g_free(adapter_path);
620 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
622 buf = __bt_tds_provider_get_tds_blocks(&length);
623 retv_if(length == 0, BLUETOOTH_ERROR_NONE);
624 retv_if(NULL == buf, BLUETOOTH_ERROR_INTERNAL);
625 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
626 for (i = 0; i < length; i++)
627 g_variant_builder_add(builder, "y", buf[i]);
630 temp = g_variant_new("ay", builder);
631 g_variant_builder_unref(builder);
632 result = g_dbus_proxy_call_sync(proxy, "SetTdsBlockData",
633 g_variant_new("(@ay)", temp),
634 G_DBUS_CALL_FLAGS_NONE, -1,
636 g_object_unref(proxy);
637 if (result == NULL) {
639 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
642 BT_ERR("Error occured in Proxy call: SetData");
644 return BLUETOOTH_ERROR_INTERNAL;
648 return BLUETOOTH_ERROR_NONE;
651 static void __bt_free_tds_transport_info(gpointer data, gpointer user_data)
653 bt_tds_transport_info_t *transport_info = data;
655 ret_if(NULL == transport_info);
659 g_free(transport_info->data);
660 g_free(transport_info);
665 static bt_tds_transport_info_t * __bt_tds_find_transport_info(
666 bt_tds_provider_t *provider, unsigned int handle)
670 retv_if(!provider, NULL);
672 for (l = provider->transports; l != NULL; l = g_slist_next(l)) {
673 bt_tds_transport_info_t *transport_info = l->data;
678 if (transport_info->tds_handle == handle)
679 return transport_info;
685 int _bt_tds_provider_register(const char *sender)
688 GDBusConnection *conn;
689 char *adapter_path = NULL;
690 GError *error = NULL;
691 GVariant *result = NULL;
692 bt_tds_provider_t *provider;
694 retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM);
698 if (__bt_tds_provider_find_from_list(sender))
699 return BLUETOOTH_ERROR_ALREADY_INITIALIZED;
701 if (0 == g_slist_length(provider_list)) {
702 /* Init adv_handle list */
703 __bt_init_adv_handle();
705 conn = _bt_gdbus_get_system_gconn();
706 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
708 adapter_path = _bt_get_adapter_path();
709 if (adapter_path == NULL) {
710 BT_ERR("Could not get adapter path\n");
711 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
714 BT_INFO("Adapter path [%s]", adapter_path);
715 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
716 NULL, BT_BLUEZ_NAME, adapter_path,
717 BT_TDS_PROVIDER_INTERFACE, NULL, NULL);
718 g_free(adapter_path);
719 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
721 result = g_dbus_proxy_call_sync(proxy, "RegisterTdsProvider",
722 NULL, G_DBUS_CALL_FLAGS_NONE, -1,
724 g_object_unref(proxy);
725 if (result == NULL) {
727 BT_ERR("Error occured in Proxy call [%s]", error->message);
730 BT_ERR("Error occured in Proxy call: RegisterTdsProvider");
732 return BLUETOOTH_ERROR_INTERNAL;
736 provider = g_malloc0(sizeof(bt_tds_provider_t));
737 provider->sender = g_strdup(sender);
738 provider->adv_handle = __bt_provider_get_adv_handle();
739 if (0 > provider->adv_handle) {
740 g_free(provider->sender);
742 return BLUETOOTH_ERROR_INTERNAL;
745 provider_list = g_slist_append(provider_list, provider);
748 return BLUETOOTH_ERROR_NONE;
751 int _bt_tds_provider_unregister(const char *sender)
754 GDBusConnection *conn;
755 char *adapter_path = NULL;
756 GError *error = NULL;
757 GVariant *result = NULL;
758 bt_tds_provider_t *provider = NULL;
761 retv_if(NULL == sender, BLUETOOTH_ERROR_NOT_INITIALIZED);
765 provider = __bt_tds_provider_find_from_list(sender);
767 return BLUETOOTH_ERROR_NOT_INITIALIZED;
769 if (1 == g_slist_length(provider_list)) {
770 conn = _bt_gdbus_get_system_gconn();
771 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
773 adapter_path = _bt_get_adapter_path();
774 if (adapter_path == NULL) {
775 BT_ERR("Could not get adapter path\n");
776 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
779 BT_INFO("Adapter path [%s]", adapter_path);
780 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
781 NULL, BT_BLUEZ_NAME, adapter_path,
782 BT_TDS_PROVIDER_INTERFACE, NULL, NULL);
784 g_free(adapter_path);
785 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
787 result = g_dbus_proxy_call_sync(proxy, "UnregisterTdsProvider",
788 NULL, G_DBUS_CALL_FLAGS_NONE, -1,
790 g_object_unref(proxy);
791 if (result == NULL) {
793 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
796 BT_ERR("Error occured in Proxy call: UnregisterTdsProvider");
798 return BLUETOOTH_ERROR_INTERNAL;
802 if (_bt_is_multi_adv_supported()) {
803 /* Disable advertisement for sender */
804 ret = _bt_set_advertising(provider->sender, provider->adv_handle, FALSE, FALSE);
805 if (ret != BLUETOOTH_ERROR_NONE)
806 BT_ERR("Failed to disable advertising with error: %d", ret);
809 * Disable advertising here. Later on receiving advertising disabled event,
810 * advertising will be enabled again with updated advertising data
812 ret = __bt_tds_disable_advertising(NULL);
813 if (ret != BLUETOOTH_ERROR_NONE)
814 BT_ERR("Failed to disable advertising with error: %d", ret);
817 provider_list = g_slist_remove(provider_list, provider);
818 g_slist_foreach(provider->transports, __bt_free_tds_transport_info, NULL);
819 g_slist_free(provider->transports);
820 __bt_provider_delete_adv_handle(provider->adv_handle);
821 g_free(provider->sender);
825 return BLUETOOTH_ERROR_NONE;
828 int _bt_tds_provider_transport_create(const char *sender, int transport, unsigned int tds_handle)
830 bt_tds_transport_info_t *transport_info;
831 bt_tds_provider_t *provider = NULL;
833 retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM);
835 if (BLUETOOTH_TDS_TRANSPORT_BT > transport ||
836 BLUETOOTH_TDS_TRANSPORT_INVALID <= transport) {
837 BT_ERR("transport value: %d not in range", transport);
838 return BLUETOOTH_ERROR_INVALID_PARAM;
843 provider = __bt_tds_provider_find_from_list(sender);
845 return BLUETOOTH_ERROR_NOT_INITIALIZED;
847 transport_info = g_malloc0(sizeof(bt_tds_transport_info_t));
848 transport_info->transport = transport;
849 transport_info->tds_handle = tds_handle;
850 transport_info->role = TDS_ROLE_PROVIDER;
851 transport_info->state = BLUETOOTH_TDS_TRANSPORT_STATE_OFF;
852 provider->transports = g_slist_append(provider->transports, transport_info);
855 return BLUETOOTH_ERROR_NONE;
858 int _bt_tds_provider_transport_remove(const char *sender, unsigned int tds_handle)
860 bt_tds_provider_t *provider = NULL;
861 bt_tds_transport_info_t *transport_info;
864 retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM);
868 provider = __bt_tds_provider_find_from_list(sender);
870 return BLUETOOTH_ERROR_INVALID_PARAM;
872 transport_info = __bt_tds_find_transport_info(provider, tds_handle);
874 return BLUETOOTH_ERROR_INVALID_PARAM;
876 provider->transports = g_slist_remove(provider->transports, transport_info);
877 __bt_free_tds_transport_info(transport_info, NULL);
879 /* Set/update transport data in gatt db */
880 ret = __bt_tds_provider_update_transport_data(provider);
881 if (BLUETOOTH_ERROR_NONE != ret) {
882 BT_ERR("Failed to update transport data with error: %d", ret);
887 * Disable advertising here. Later on receiving advertising disabled event,
888 * advertising will be enabled again with updated advertising data.
890 if (_bt_is_multi_adv_supported())
891 ret = __bt_tds_disable_advertising(provider);
893 ret = __bt_tds_disable_advertising(NULL);
894 if (ret != BLUETOOTH_ERROR_NONE) {
895 BT_ERR("Failed to enable advertising with error: %d", ret);
900 return BLUETOOTH_ERROR_NONE;
903 int _bt_tds_provider_set_manuf_data(char *sender, unsigned char *data, unsigned int len)
905 bt_tds_provider_t *provider;
908 retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM);
909 retv_if(len == 0 || len > TDS_MANUF_DATA_LEN_MAX, BLUETOOTH_ERROR_INVALID_PARAM);
910 retv_if(NULL == data, BLUETOOTH_ERROR_INVALID_PARAM);
914 BT_INFO("sender: %s", sender);
915 provider = __bt_tds_provider_find_from_list(sender);
917 return BLUETOOTH_ERROR_INVALID_PARAM;
920 * Set manufacturer data and disable advertising here. Later on receiving advertising
921 * disabled event, advertising will be enabled again with updated advertising data.
923 if (_bt_is_multi_adv_supported()) {
924 g_free(provider->manuf_data);
925 provider->manuf_data_len = len;
926 provider->manuf_data = g_malloc0(provider->manuf_data_len);
927 memcpy(provider->manuf_data, data, len);
929 ret = __bt_tds_disable_advertising(provider);
931 manuf_data_len = len;
932 memcpy(manuf_data, data, len);
933 ret = __bt_tds_disable_advertising(NULL);
935 if (ret != BLUETOOTH_ERROR_NONE) {
936 BT_ERR("Failed to enable advertising with error: %d", ret);
941 return BLUETOOTH_ERROR_NONE;
944 int _bt_tds_provider_set_transport_data(char *sender, int tds_handle,
945 int transport_state, unsigned char *data, unsigned int len)
947 bt_tds_provider_t *provider;
948 bt_tds_transport_info_t *transport_info;
951 retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM);
952 retv_if(len > 0 && NULL == data, BLUETOOTH_ERROR_INVALID_PARAM);
956 if (BLUETOOTH_TDS_TRANSPORT_STATE_OFF > transport_state ||
957 BLUETOOTH_TDS_TRANSPORT_STATE_RESERVED <= transport_state) {
958 BT_ERR("transport_state value: %d not in range", transport_state);
959 return BLUETOOTH_ERROR_INVALID_PARAM;
962 BT_INFO("sender: %s, tds_handle: %X", sender, tds_handle);
963 provider = __bt_tds_provider_find_from_list(sender);
965 return BLUETOOTH_ERROR_INVALID_PARAM;
967 transport_info = __bt_tds_find_transport_info(provider, tds_handle);
969 return BLUETOOTH_ERROR_INVALID_PARAM;
971 transport_info->state = transport_state;
972 g_free(transport_info->data);
973 transport_info->data_len = len + 3;
974 transport_info->data = g_malloc0(transport_info->data_len);
975 /* TDS Orgnazition Id */
976 transport_info->data[0] = __bt_tds_get_organization_id(transport_info->transport);
978 if (TDS_ROLE_SEEKER_PROVIDER != __bt_tds_get_role(transport_info->data[1]))
979 transport_info->data[1] = __bt_tds_set_role(transport_info->data[1], transport_info->role);
980 transport_info->data[1] = __bt_tds_set_transport_data_incomplete(transport_info->data[1], FALSE);
981 transport_info->data[1] = __bt_tds_set_transport_state(transport_info->data[1], transport_state);
982 /* TDS block data length */
983 transport_info->data[2] = len;
984 memcpy(&(transport_info->data[3]), data, len);
986 /* Set/update transport data in gatt db */
987 ret = __bt_tds_provider_update_transport_data(provider);
988 if (BLUETOOTH_ERROR_NONE != ret) {
989 BT_ERR("Failed to update transport data with error: %d", ret);
994 * Disable advertising here. Later on receiving advertising disabled event,
995 * advertising will be enabled again with updated advertising data.
997 if (_bt_is_multi_adv_supported())
998 ret = __bt_tds_disable_advertising(provider);
1000 ret = __bt_tds_disable_advertising(NULL);
1001 if (ret != BLUETOOTH_ERROR_NONE) {
1002 BT_ERR("Failed to enable advertising with error: %d", ret);
1007 return BLUETOOTH_ERROR_NONE;
1010 static int __bt_tds_send_activation_response(char *address,
1011 unsigned char response, unsigned char *data, unsigned int len)
1014 GDBusConnection *conn;
1016 GError *error = NULL;
1017 GVariant *result = NULL;
1018 GVariantBuilder *builder;
1022 retv_if(NULL == address, BLUETOOTH_ERROR_INVALID_PARAM);
1023 retv_if(NULL == data, BLUETOOTH_ERROR_INVALID_PARAM);
1026 conn = _bt_gdbus_get_system_gconn();
1027 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1029 device_path = _bt_get_device_object_path(address);
1030 if (NULL == device_path) {
1031 BT_ERR("Could not get device path\n");
1032 return BLUETOOTH_ERROR_INTERNAL;
1035 BT_INFO("Device path [%s]", device_path);
1036 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1037 NULL, BT_BLUEZ_NAME, device_path,
1038 BT_TDS_PROVIDER_INTERFACE, NULL, NULL);
1039 g_free(device_path);
1040 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1042 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1043 for (i = 0; i < len; i++)
1044 g_variant_builder_add(builder, "y", data[i]);
1046 temp = g_variant_new("ay", builder);
1047 g_variant_builder_unref(builder);
1048 result = g_dbus_proxy_call_sync(proxy, "TdsActivationResponse",
1049 g_variant_new("(y@ay)", response, temp),
1050 G_DBUS_CALL_FLAGS_NONE, -1,
1052 g_object_unref(proxy);
1053 if (result == NULL) {
1054 if (error != NULL) {
1055 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
1056 g_error_free(error);
1058 BT_ERR("Error occured in Proxy call: SetData");
1060 return BLUETOOTH_ERROR_INTERNAL;
1064 return BLUETOOTH_ERROR_NONE;
1067 int _bt_tds_provider_send_activation_response(char *sender, unsigned int tds_handle,
1068 bluetooth_device_address_t *address, int response, unsigned char *data, unsigned int len)
1070 bt_tds_provider_t *provider;
1071 bt_tds_transport_info_t *transport_info;
1073 char addr[BT_ADDRESS_STRING_SIZE];
1076 retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM);
1077 retv_if(NULL == address, BLUETOOTH_ERROR_INVALID_PARAM);
1078 retv_if(NULL == data, BLUETOOTH_ERROR_INVALID_PARAM);
1082 BT_INFO("sender: %s, tds_handle: 0x%X", sender, tds_handle);
1083 provider = __bt_tds_provider_find_from_list(sender);
1085 return BLUETOOTH_ERROR_NOT_INITIALIZED;
1087 transport_info = __bt_tds_find_transport_info(provider, tds_handle);
1088 if (!transport_info)
1089 return BLUETOOTH_ERROR_INVALID_PARAM;
1091 if (BLUETOOTH_ERROR_NONE == response) {
1092 /* Activation success, set transport state enabled */
1093 _bt_tds_provider_set_transport_data(provider->sender,
1094 transport_info->transport, BLUETOOTH_TDS_TRANSPORT_STATE_ON,
1095 transport_info->data, transport_info->data_len);
1098 _bt_convert_addr_type_to_string(addr, address->addr);
1099 resp = __bt_tds_get_activation_response_code(response);
1101 ret = __bt_tds_send_activation_response(addr, resp, data, len);
1102 if (ret != BLUETOOTH_ERROR_NONE) {
1103 BT_ERR("Failed to send activation response with error: %d", ret);
1108 return BLUETOOTH_ERROR_NONE;
1111 void _bt_tds_handle_activation_request(const char *path,
1112 unsigned char org_id, unsigned char *buf, int len)
1115 char *address = NULL;
1122 ret_if(NULL == path);
1123 ret_if(len > 0 && NULL == buf);
1127 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1128 _bt_convert_device_path_to_address(path, address);
1129 transport = __bt_tds_get_transport(org_id);
1130 BT_DBG("Address: %s, transport: %.2X", address, transport);
1132 if (BLUETOOTH_TDS_TRANSPORT_INVALID == transport)
1135 tds_data = g_variant_new_from_data((const GVariantType *)"ay",
1136 buf, len, TRUE, NULL, NULL);
1137 param = g_variant_new("(si@ay)", address, transport, tds_data);
1139 /* Find provider with transport type in list and send event to them */
1140 for (l = provider_list; l != NULL; l = g_slist_next(l)) {
1141 bt_tds_provider_t *provider = l->data;
1146 for (l1 = provider->transports; l1 != NULL; l1 = g_slist_next(l1)) {
1147 bt_tds_transport_info_t *transport_info = l1->data;
1149 if (transport_info && transport_info->transport == transport) {
1150 _bt_send_event_to_dest(provider->sender, BT_TDS_EVENT,
1151 BLUETOOTH_EVENT_TDS_ACTIVATION_REQUESTED, param);
1157 /* If no provider found for transport type, send error */
1166 /* send activation response as error to bluez */
1167 __bt_tds_send_activation_response(address,
1168 TDS_CONTROL_POINT_RESPONSE_UNSUPPORTED_ORG_ID, NULL, 0);
1172 void _bt_tds_stop_by_terminated_process(char *name)
1174 bt_tds_provider_t *provider = NULL;
1176 provider = __bt_tds_provider_find_from_list(name);
1180 _bt_tds_provider_unregister(provider->sender);
1183 void _bt_tds_handle_adv_disabled(const char *sender, int adv_handle)
1185 bt_tds_provider_t *provider = NULL;
1187 BT_INFO("sender: %s, adv_handle:%d", sender, adv_handle);
1189 ret_if(NULL == sender);
1191 if (g_strcmp0(sender, "bt-service") != 0) {
1192 provider = __bt_tds_provider_find_from_list(sender);
1193 if (!provider || provider->adv_handle != adv_handle) {
1194 BT_INFO("Provider not found");
1198 if (adv_handle != 0)
1202 __bt_tds_set_advertising(provider);
1205 static void __bt_tds_transport_data_read_desc_cb(GObject *source_object,
1206 GAsyncResult *res, gpointer user_data)
1208 GError *error = NULL;
1209 bt_gatt_char_descriptor_property_t att_value = { 0, };
1210 GDBusConnection *system_gconn = NULL;
1211 GVariant *value = NULL;
1212 GByteArray *gp_byte_array = NULL;
1213 GVariantIter *iter = NULL;
1215 bt_tds_data_read_req_info *info = NULL;
1216 GVariant *out_param1;
1217 request_info_t *req_info = NULL;
1218 bluetooth_device_address_t device_addr = { {0} };
1219 int result = BLUETOOTH_ERROR_NONE;
1222 GVariant *var_data, *param = NULL;
1223 char *tds_data = NULL;
1227 system_gconn = _bt_gdbus_get_system_gconn();
1229 address = (char *)user_data;
1230 info = __bt_tds_data_read_info_by_address(address);
1232 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1235 BT_ERR("Error : %s \n", error->message);
1238 req_info = _bt_get_request_info(info->req_id);
1239 __bt_tds_remove_data_read_req_info(info);
1241 result = BLUETOOTH_ERROR_INTERNAL;
1245 gp_byte_array = g_byte_array_new();
1246 g_variant_get(value, "(ay)", &iter);
1248 while (g_variant_iter_loop(iter, "y", &g_byte))
1249 g_byte_array_append(gp_byte_array, &g_byte, 1);
1251 if (gp_byte_array->len != 0) {
1252 att_value.val_len = (unsigned int)gp_byte_array->len;
1253 att_value.val = (unsigned char *)gp_byte_array->data;
1256 tds_data = (char *)g_memdup(att_value.val, att_value.val_len);
1258 var_data = g_variant_new_from_data((const GVariantType *)"ay",
1259 tds_data, att_value.val_len, TRUE, NULL, NULL);
1262 param = g_variant_new("(isn@ay)", result, address, att_value.val_len, var_data);
1263 _bt_send_event_to_dest(info->sender, BT_TDS_EVENT,
1264 BLUETOOTH_EVENT_TDS_TRANSPORT_DATA_RECEIVED,
1266 req_info = _bt_get_request_info(info->req_id);
1267 __bt_tds_remove_data_read_req_info(info);
1271 for (k = 0; k < att_value.val_len; k++)
1272 BT_DBG("Transport Data[%d] = [0x%x]", k, att_value.val[k]);
1275 if (req_info == NULL) {
1276 BT_ERR("TDS Complete data read Request is not found!!");
1280 if (req_info->context == NULL)
1283 _bt_convert_addr_string_to_type(device_addr.addr,
1284 (const char *)address);
1286 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
1287 &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
1288 g_dbus_method_invocation_return_value(req_info->context,
1289 g_variant_new("(iv)", result, out_param1));
1291 _bt_delete_request_list(req_info->req_id);
1296 g_clear_error(&error);
1298 g_byte_array_free(gp_byte_array, TRUE);
1302 g_variant_unref(value);
1304 g_variant_iter_free(iter);
1310 int _bt_tds_read_transport_data(int request_id, char *sender,
1311 bluetooth_device_address_t *dev_addr, char *handle)
1313 GDBusConnection *conn;
1314 char *address = NULL;
1315 bt_tds_data_read_req_info *info = NULL;
1317 BT_CHECK_PARAMETER(handle, return);
1318 BT_CHECK_PARAMETER(sender, return);
1319 BT_CHECK_PARAMETER(dev_addr, return);
1321 conn = _bt_gdbus_get_system_gconn();
1322 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1324 BT_DBG("Read Complete TDS block from Provider [Handle] [%s]", handle);
1325 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1326 _bt_convert_addr_type_to_string(address, dev_addr->addr);
1328 /* If TDS data read already pending on same Provider, then return In progress */
1329 if (__bt_tds_data_read_info_by_address(address) != NULL) {
1330 BT_ERR("TDS Data Read Req is ongoing in remote provider [%s]", address);
1332 return BLUETOOTH_ERROR_IN_PROGRESS;
1335 g_dbus_connection_call(conn,
1338 GATT_DESC_INTERFACE,
1341 G_VARIANT_TYPE("(ay)"),
1342 G_DBUS_CALL_FLAGS_NONE,
1345 (GAsyncReadyCallback)__bt_tds_transport_data_read_desc_cb,
1348 /* Save Info in pending list */
1349 info = g_malloc0(sizeof(bt_tds_data_read_req_info));
1350 info->remote_address = g_strdup(address);
1351 info->sender = g_strdup(sender);
1352 info->req_id = request_id;
1353 tds_data_read_req_info_list = g_slist_append(tds_data_read_req_info_list, info);
1356 return BLUETOOTH_ERROR_NONE;
1359 static void __bluetooth_internal_control_point_enable_request_cb(GObject *source_object,
1360 GAsyncResult *res, gpointer user_data)
1362 GError *error = NULL;
1363 GDBusConnection *system_gconn = NULL;
1364 GVariant *value = NULL;
1365 GVariant *param = NULL;
1366 GVariant *out_param1 = NULL;
1367 int result = BLUETOOTH_ERROR_NONE;
1368 char *address = NULL;
1369 bt_tds_activation_info *info = NULL;
1370 request_info_t *req_info = NULL;
1371 bluetooth_device_address_t device_addr = { {0} };
1374 system_gconn = _bt_gdbus_get_system_gconn();
1375 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1378 BT_ERR("Error : %s \n", error->message);
1379 if (g_strrstr(error->message, "Already notifying"))
1380 result = BLUETOOTH_ERROR_NONE;
1381 else if (g_strrstr(error->message, "In Progress"))
1382 result = BLUETOOTH_ERROR_IN_PROGRESS;
1383 else if (g_strrstr(error->message, "Operation is not supported"))
1384 result = BLUETOOTH_ERROR_NOT_SUPPORT;
1385 else if (g_strrstr(error->message, "Write not permitted") ||
1386 g_strrstr(error->message, "Operation Not Authorized"))
1387 result = BLUETOOTH_ERROR_PERMISSION_DEINED;
1388 else if (g_strrstr(error->message, "Not paired"))
1389 result = BLUETOOTH_ERROR_NOT_PAIRED;
1391 result = BLUETOOTH_ERROR_INTERNAL;
1393 BT_DBG("TDS CCCD enable request successful, send event to BT App");
1396 address = (char *)user_data;
1397 info = __bt_tds_activation_info_by_address(address);
1400 req_info = _bt_get_request_info(info->req_id);
1402 /* If CCCD Enable request failed for any reason, reset timer */
1403 if (result != BLUETOOTH_ERROR_NONE && info != NULL) {
1404 BT_ERR("Activation Request failed");
1406 if (info->activation_timeout_id > 0) {
1407 g_source_remove(info->activation_timeout_id);
1408 info->activation_timeout_id = 0;
1411 /* Remove Indication Info */
1412 __bt_tds_remove_indication_info(info);
1414 /* CCCD Enable Request successful */
1416 param = g_variant_new("(is)", result, address);
1417 _bt_send_event_to_dest(info->sender, BT_TDS_EVENT,
1418 BLUETOOTH_EVENT_TDS_CONTROL_POINT_ENABLED,
1423 if (req_info == NULL) {
1424 BT_ERR("TDS Control Point CCCD Enable Request is not found!!");
1428 if (req_info->context == NULL)
1431 _bt_convert_addr_string_to_type(device_addr.addr,
1432 (const char *)address);
1434 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
1435 &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
1436 g_dbus_method_invocation_return_value(req_info->context,
1437 g_variant_new("(iv)", result, out_param1));
1439 _bt_delete_request_list(req_info->req_id);
1443 g_variant_unref(value);
1445 g_clear_error(&error);
1453 int _bt_tds_enable_control_point(int request_id, char *sender, bluetooth_device_address_t *dev_addr,
1456 GDBusConnection *conn;
1457 char *address = NULL;
1458 bt_tds_activation_info *info = NULL;
1460 BT_CHECK_PARAMETER(handle, return);
1461 BT_CHECK_PARAMETER(sender, return);
1462 BT_CHECK_PARAMETER(dev_addr, return);
1464 conn = _bt_gdbus_get_system_gconn();
1465 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1467 BT_DBG("TDS Control point CCCD Handle [%s]", handle);
1469 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1470 _bt_convert_addr_type_to_string(address, dev_addr->addr);
1472 if (__bt_tds_activation_info_by_address(address) != NULL) {
1473 BT_ERR("Activation is already ongoing for same remote provider");
1475 return BLUETOOTH_ERROR_IN_PROGRESS;
1478 BT_INFO("Start Notify to Bluez");
1479 g_dbus_connection_call(conn,
1482 GATT_CHAR_INTERFACE,
1486 G_DBUS_CALL_FLAGS_NONE,
1487 GATT_DEFAULT_TIMEOUT, NULL,
1488 (GAsyncReadyCallback)__bluetooth_internal_control_point_enable_request_cb,
1491 info = g_malloc0(sizeof(bt_tds_activation_info));
1492 info->remote_address = g_strdup(address);
1493 info->sender = g_strdup(sender);
1494 info->req_id = request_id;
1495 tds_activation_info_list = g_slist_append(tds_activation_info_list, info);
1498 return BLUETOOTH_ERROR_NONE;
1501 static void __bluetooth_internal_activation_request_cb(GObject *source_object,
1502 GAsyncResult *res, gpointer user_data)
1504 GError *error = NULL;
1505 GDBusConnection *system_gconn = NULL;
1506 GVariant *value = NULL;
1507 GVariant *param = NULL;
1508 GVariant *out_param1 = NULL;
1509 int result = BLUETOOTH_ERROR_NONE;
1510 guint8 att_ecode = 0;
1511 char *address = NULL;
1512 bt_tds_activation_info *info = NULL;
1513 request_info_t *req_info = NULL;
1514 bluetooth_device_address_t device_addr = { {0} };
1517 system_gconn = _bt_gdbus_get_system_gconn();
1518 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1521 BT_ERR("Error : %s \n", error->message);
1522 result = BLUETOOTH_ERROR_INTERNAL;
1524 g_variant_get(value, "(y)", &att_ecode);
1526 result = BLUETOOTH_ERROR_INTERNAL;
1527 BT_ERR("ATT Error code: %d \n", att_ecode);
1531 address = (char *)user_data;
1532 info = __bt_tds_activation_info_by_address(address);
1534 req_info = _bt_get_request_info(info->req_id);
1536 /* Is Activation request failed for any reason, reset timer */
1537 if (result != BLUETOOTH_ERROR_NONE && info != NULL) {
1538 BT_ERR("Activation Request failed");
1540 if (info->activation_timeout_id > 0) {
1541 g_source_remove(info->activation_timeout_id);
1542 info->activation_timeout_id = 0;
1545 /* Remove Indication Info */
1546 __bt_tds_remove_indication_info(info);
1548 /* Activation Request successful */
1550 param = g_variant_new("(is)", result, address);
1551 _bt_send_event_to_dest(info->sender, BT_TDS_EVENT,
1552 BLUETOOTH_EVENT_TDS_ACTIVATION_RESULT,
1557 if (req_info == NULL) {
1558 BT_ERR("TDS Control Point Activation Request is not found!!");
1562 if (req_info->context == NULL)
1565 _bt_convert_addr_string_to_type(device_addr.addr,
1566 (const char *)address);
1568 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
1569 &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
1570 g_dbus_method_invocation_return_value(req_info->context,
1571 g_variant_new("(iv)", result, out_param1));
1573 _bt_delete_request_list(req_info->req_id);
1577 g_variant_unref(value);
1579 g_clear_error(&error);
1587 static bool __bt_tds_indication_timeout_cb(gpointer user_data)
1589 char *address = NULL;
1590 address = (char*) user_data;
1591 bt_tds_activation_info *info = NULL;
1592 /* Indication:Fail*/
1593 unsigned char buffer[2] = {0x01, 0x04};
1595 BT_DBG("Activation timer Expired [Provider] [%s]", address);
1597 info = __bt_tds_activation_info_by_address(address);
1599 __bt_tds_send_indication_event(info, buffer, sizeof(buffer));
1603 int _bt_tds_activate_control_point(int request_id, char *sender, bluetooth_device_address_t *dev_addr,
1604 char *handle, unsigned char *param, int length)
1607 GVariantBuilder *builder;
1609 bt_tds_activation_info *info = NULL;
1610 GDBusConnection *conn;
1611 char *address = NULL;
1614 BT_CHECK_PARAMETER(handle, return);
1615 BT_CHECK_PARAMETER(sender, return);
1616 BT_CHECK_PARAMETER(dev_addr, return);
1617 BT_CHECK_PARAMETER(param, return);
1619 conn = _bt_gdbus_get_system_gconn();
1620 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1622 BT_DBG("TDS Control point Activate handle [%s] data length [%d]", handle, length);
1623 /* Check if activation is ongoing for the same Remote Provider */
1624 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1625 _bt_convert_addr_type_to_string(address, dev_addr->addr);
1627 info = __bt_tds_activation_info_by_address(address);
1628 if (info && info->activation_timeout_id > 0) {
1629 BT_ERR("Activation is already ongoing in remote provider");
1631 return BLUETOOTH_ERROR_IN_PROGRESS;
1634 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1636 for (i = 0; i < length; i++)
1637 g_variant_builder_add(builder, "y", param[i]);
1639 val = g_variant_new("(ay)", builder);
1641 /* Activate Control Point */
1642 g_dbus_connection_call(conn,
1645 GATT_CHAR_INTERFACE,
1648 G_VARIANT_TYPE("(y)"),
1649 G_DBUS_CALL_FLAGS_NONE,
1651 (GAsyncReadyCallback)__bluetooth_internal_activation_request_cb,
1654 g_variant_builder_unref(builder);
1657 info = g_malloc0(sizeof(bt_tds_activation_info));
1658 info->remote_address = g_strdup(address);
1659 info->sender = g_strdup(sender);
1660 tds_activation_info_list = g_slist_append(tds_activation_info_list, info);
1662 info->req_id = request_id;
1663 info->activation_timeout_id = g_timeout_add(BT_TRANSPORT_ACTIVATION_TIMEOUT_MAX,
1664 (GSourceFunc)__bt_tds_indication_timeout_cb, (gpointer)info->remote_address);
1667 return BLUETOOTH_ERROR_NONE;
1670 static bt_tds_activation_info* __bt_tds_activation_info_by_address(char *address)
1673 bt_tds_activation_info *info = NULL;
1675 for (l = tds_activation_info_list; l != NULL; l = g_slist_next(l)) {
1676 info = (bt_tds_activation_info*)l->data;
1680 if (!g_strcmp0(info->remote_address, address)) {
1681 BT_INFO("Seeker found waiting for Ind from Provider addr[%s]",
1682 info->remote_address);
1689 static bt_tds_data_read_req_info* __bt_tds_data_read_info_by_address(char *address)
1692 bt_tds_data_read_req_info *info = NULL;
1694 for (l = tds_data_read_req_info_list; l != NULL; l = g_slist_next(l)) {
1695 info = (bt_tds_data_read_req_info*)l->data;
1699 if (!g_strcmp0(info->remote_address, address)) {
1700 BT_INFO("Found waiting for Transport Data Read from Provider addr[%s]",
1701 info->remote_address);
1708 static void __bt_tds_remove_indication_info(bt_tds_activation_info *info)
1710 BT_DBG("Removing Indication Info [%s]", info->remote_address);
1712 tds_activation_info_list = g_slist_remove(tds_activation_info_list, info);
1713 if (info->remote_address)
1714 g_free(info->remote_address);
1716 g_free(info->sender);
1717 if (info->activation_timeout_id > 0) {
1718 g_source_remove(info->activation_timeout_id);
1719 info->activation_timeout_id = 0;
1724 static void __bt_tds_remove_data_read_req_info(bt_tds_data_read_req_info *info)
1726 BT_DBG("Removing Read Req Info [%s]", info->remote_address);
1728 tds_data_read_req_info_list = g_slist_remove(tds_data_read_req_info_list, info);
1729 if (info->remote_address)
1730 g_free(info->remote_address);
1732 g_free(info->sender);
1736 static void __bt_tds_send_indication_event(bt_tds_activation_info *info,
1737 unsigned char *buffer, int len)
1742 tds_data = g_variant_new_from_data((const GVariantType *)"ay",
1743 buffer, len, TRUE, NULL, NULL);
1745 BT_DBG("Send Indication event to sender");
1746 param = g_variant_new("(s@ay)", info->remote_address, tds_data);
1747 _bt_send_event_to_dest(info->sender, BT_TDS_EVENT,
1748 BLUETOOTH_EVENT_TDS_ACTIVATION_INDICATION,
1751 /* Remove info from list */
1752 __bt_tds_remove_indication_info(info);
1755 void _bt_tds_check_indication(const char *path, GVariant *msg)
1757 char address[BT_ADDRESS_STRING_SIZE] = {0};
1758 bt_tds_activation_info *info = NULL;
1759 unsigned char *buffer = NULL;
1762 GVariant *value = NULL;
1765 _bt_convert_device_path_to_address(path, address);
1766 info = __bt_tds_activation_info_by_address(address);
1769 g_variant_get(msg, "(is@ay)", NULL, NULL, &value);
1770 len = g_variant_get_size(value);
1771 BT_DBG("Indication data from Provider len[%d]", len);
1773 buffer = (unsigned char *)g_variant_get_data(value);
1775 for (i = 0; i < len; i++)
1776 BT_DBG("%.2x", buffer[i]);
1780 if (info->activation_timeout_id > 0)
1781 g_source_remove(info->activation_timeout_id);
1783 /* Send Indication & info removed internally */
1784 __bt_tds_send_indication_event(info, buffer, len);
1786 g_variant_unref(value);