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);
1237 req_info = _bt_get_request_info(info->req_id);
1238 __bt_tds_remove_data_read_req_info(info);
1240 result = BLUETOOTH_ERROR_INTERNAL;
1244 gp_byte_array = g_byte_array_new();
1245 g_variant_get(value, "(ay)", &iter);
1247 while (g_variant_iter_loop(iter, "y", &g_byte))
1248 g_byte_array_append(gp_byte_array, &g_byte, 1);
1250 if (gp_byte_array->len != 0) {
1251 att_value.val_len = (unsigned int)gp_byte_array->len;
1252 att_value.val = (unsigned char *)gp_byte_array->data;
1255 tds_data = (char *)g_memdup(att_value.val, att_value.val_len);
1257 var_data = g_variant_new_from_data((const GVariantType *)"ay",
1258 tds_data, att_value.val_len, TRUE, NULL, NULL);
1261 param = g_variant_new("(isn@ay)", result, address, att_value.val_len, var_data);
1262 _bt_send_event_to_dest(info->sender, BT_TDS_EVENT,
1263 BLUETOOTH_EVENT_TDS_TRANSPORT_DATA_RECEIVED,
1265 req_info = _bt_get_request_info(info->req_id);
1266 __bt_tds_remove_data_read_req_info(info);
1270 for (k = 0; k < att_value.val_len; k++)
1271 BT_DBG("Transport Data[%d] = [0x%x]", k, att_value.val[k]);
1274 if (req_info == NULL) {
1275 BT_ERR("TDS Complete data read Request is not found!!");
1279 if (req_info->context == NULL)
1282 _bt_convert_addr_string_to_type(device_addr.addr,
1283 (const char *)address);
1285 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
1286 &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
1287 g_dbus_method_invocation_return_value(req_info->context,
1288 g_variant_new("(iv)", result, out_param1));
1290 _bt_delete_request_list(req_info->req_id);
1295 g_clear_error(&error);
1297 g_byte_array_free(gp_byte_array, TRUE);
1301 g_variant_unref(value);
1303 g_variant_iter_free(iter);
1309 int _bt_tds_read_transport_data(int request_id, char *sender,
1310 bluetooth_device_address_t *dev_addr, char *handle)
1312 GDBusConnection *conn;
1313 char *address = NULL;
1314 bt_tds_data_read_req_info *info = NULL;
1315 GVariantBuilder *builder = NULL;
1318 BT_CHECK_PARAMETER(handle, return);
1319 BT_CHECK_PARAMETER(sender, return);
1320 BT_CHECK_PARAMETER(dev_addr, return);
1322 conn = _bt_gdbus_get_system_gconn();
1323 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1325 BT_DBG("Read Complete TDS block from Provider [Handle] [%s]", handle);
1326 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1327 _bt_convert_addr_type_to_string(address, dev_addr->addr);
1329 /* If TDS data read already pending on same Provider, then return In progress */
1330 if (__bt_tds_data_read_info_by_address(address) != NULL) {
1331 BT_ERR("TDS Data Read Req is ongoing in remote provider [%s]", address);
1333 return BLUETOOTH_ERROR_IN_PROGRESS;
1336 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1338 g_variant_builder_add(builder, "{sv}", "offset",
1339 g_variant_new("q", offset));
1341 g_dbus_connection_call(conn, BT_BLUEZ_NAME, handle,
1342 GATT_DESC_INTERFACE,
1344 g_variant_new("(a{sv})", builder),
1345 G_VARIANT_TYPE("(ay)"),
1346 G_DBUS_CALL_FLAGS_NONE,
1349 (GAsyncReadyCallback)__bt_tds_transport_data_read_desc_cb,
1352 g_variant_builder_unref(builder);
1354 /* Save Info in pending list */
1355 info = g_malloc0(sizeof(bt_tds_data_read_req_info));
1356 info->remote_address = g_strdup(address);
1357 info->sender = g_strdup(sender);
1358 info->req_id = request_id;
1359 tds_data_read_req_info_list = g_slist_append(tds_data_read_req_info_list, info);
1362 return BLUETOOTH_ERROR_NONE;
1365 static void __bluetooth_internal_control_point_enable_request_cb(GObject *source_object,
1366 GAsyncResult *res, gpointer user_data)
1368 GError *error = NULL;
1369 GDBusConnection *system_gconn = NULL;
1370 GVariant *value = NULL;
1371 GVariant *param = NULL;
1372 GVariant *out_param1 = NULL;
1373 int result = BLUETOOTH_ERROR_NONE;
1374 char *address = NULL;
1375 bt_tds_activation_info *info = NULL;
1376 request_info_t *req_info = NULL;
1377 bluetooth_device_address_t device_addr = { {0} };
1380 system_gconn = _bt_gdbus_get_system_gconn();
1381 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1384 BT_ERR("Error : %s \n", error->message);
1385 if (g_strrstr(error->message, "Already notifying"))
1386 result = BLUETOOTH_ERROR_NONE;
1387 else if (g_strrstr(error->message, "In Progress"))
1388 result = BLUETOOTH_ERROR_IN_PROGRESS;
1389 else if (g_strrstr(error->message, "Operation is not supported"))
1390 result = BLUETOOTH_ERROR_NOT_SUPPORT;
1391 else if (g_strrstr(error->message, "Write not permitted") ||
1392 g_strrstr(error->message, "Operation Not Authorized"))
1393 result = BLUETOOTH_ERROR_PERMISSION_DEINED;
1394 else if (g_strrstr(error->message, "Not paired"))
1395 result = BLUETOOTH_ERROR_NOT_PAIRED;
1397 result = BLUETOOTH_ERROR_INTERNAL;
1399 BT_DBG("TDS CCCD enable request successful, send event to BT App");
1402 address = (char *)user_data;
1403 info = __bt_tds_activation_info_by_address(address);
1406 req_info = _bt_get_request_info(info->req_id);
1408 /* If CCCD Enable request failed for any reason, reset timer */
1409 if (result != BLUETOOTH_ERROR_NONE && info != NULL) {
1410 BT_ERR("Activation Request failed");
1412 if (info->activation_timeout_id > 0) {
1413 g_source_remove(info->activation_timeout_id);
1414 info->activation_timeout_id = 0;
1417 /* Remove Indication Info */
1418 __bt_tds_remove_indication_info(info);
1420 /* CCCD Enable Request successful */
1422 param = g_variant_new("(is)", result, address);
1423 _bt_send_event_to_dest(info->sender, BT_TDS_EVENT,
1424 BLUETOOTH_EVENT_TDS_CONTROL_POINT_ENABLED,
1429 if (req_info == NULL) {
1430 BT_ERR("TDS Control Point CCCD Enable Request is not found!!");
1434 if (req_info->context == NULL)
1437 _bt_convert_addr_string_to_type(device_addr.addr,
1438 (const char *)address);
1440 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
1441 &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
1442 g_dbus_method_invocation_return_value(req_info->context,
1443 g_variant_new("(iv)", result, out_param1));
1445 _bt_delete_request_list(req_info->req_id);
1449 g_variant_unref(value);
1451 g_clear_error(&error);
1459 int _bt_tds_enable_control_point(int request_id, char *sender, bluetooth_device_address_t *dev_addr,
1462 GDBusConnection *conn;
1463 char *address = NULL;
1464 bt_tds_activation_info *info = NULL;
1466 BT_CHECK_PARAMETER(handle, return);
1467 BT_CHECK_PARAMETER(sender, return);
1468 BT_CHECK_PARAMETER(dev_addr, return);
1470 conn = _bt_gdbus_get_system_gconn();
1471 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1473 BT_DBG("TDS Control point CCCD Handle [%s]", handle);
1475 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1476 _bt_convert_addr_type_to_string(address, dev_addr->addr);
1478 if (__bt_tds_activation_info_by_address(address) != NULL) {
1479 BT_ERR("Activation is already ongoing for same remote provider");
1481 return BLUETOOTH_ERROR_IN_PROGRESS;
1484 BT_INFO("Start Notify to Bluez");
1485 g_dbus_connection_call(conn,
1488 GATT_CHAR_INTERFACE,
1492 G_DBUS_CALL_FLAGS_NONE,
1493 GATT_DEFAULT_TIMEOUT, NULL,
1494 (GAsyncReadyCallback)__bluetooth_internal_control_point_enable_request_cb,
1497 info = g_malloc0(sizeof(bt_tds_activation_info));
1498 info->remote_address = g_strdup(address);
1499 info->sender = g_strdup(sender);
1500 info->req_id = request_id;
1501 tds_activation_info_list = g_slist_append(tds_activation_info_list, info);
1504 return BLUETOOTH_ERROR_NONE;
1507 static int __bluetooth_get_att_error_code(GError *error)
1513 BT_ERR("Error : %s", error->message);
1514 str = g_strrstr(error->message, "ATT error: 0x");
1517 att_ecode = g_ascii_xdigit_value(str[len-2]) << 4;
1518 att_ecode += g_ascii_xdigit_value(str[len-1]);
1520 return BLUETOOTH_ATT_ERROR_INTERNAL;
1525 static void __bluetooth_internal_activation_request_cb(GObject *source_object,
1526 GAsyncResult *res, gpointer user_data)
1528 GError *error = NULL;
1529 GDBusConnection *system_gconn = NULL;
1530 GVariant *value = NULL;
1531 GVariant *param = NULL;
1532 GVariant *out_param1 = NULL;
1533 int result = BLUETOOTH_ERROR_NONE;
1534 char *address = NULL;
1535 bt_tds_activation_info *info = NULL;
1536 request_info_t *req_info = NULL;
1537 bluetooth_device_address_t device_addr = { {0} };
1540 system_gconn = _bt_gdbus_get_system_gconn();
1541 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1544 result = __bluetooth_get_att_error_code(error);
1546 address = (char *)user_data;
1547 info = __bt_tds_activation_info_by_address(address);
1549 req_info = _bt_get_request_info(info->req_id);
1551 /* Is Activation request failed for any reason, reset timer */
1552 if (result != BLUETOOTH_ERROR_NONE && info != NULL) {
1553 BT_ERR("Activation Request failed");
1555 if (info->activation_timeout_id > 0) {
1556 g_source_remove(info->activation_timeout_id);
1557 info->activation_timeout_id = 0;
1560 /* Remove Indication Info */
1561 __bt_tds_remove_indication_info(info);
1563 /* Activation Request successful */
1565 param = g_variant_new("(is)", result, address);
1566 _bt_send_event_to_dest(info->sender, BT_TDS_EVENT,
1567 BLUETOOTH_EVENT_TDS_ACTIVATION_RESULT,
1572 if (req_info == NULL) {
1573 BT_ERR("TDS Control Point Activation Request is not found!!");
1577 if (req_info->context == NULL)
1580 _bt_convert_addr_string_to_type(device_addr.addr,
1581 (const char *)address);
1583 out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
1584 &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
1585 g_dbus_method_invocation_return_value(req_info->context,
1586 g_variant_new("(iv)", result, out_param1));
1588 _bt_delete_request_list(req_info->req_id);
1592 g_variant_unref(value);
1594 g_clear_error(&error);
1602 static bool __bt_tds_indication_timeout_cb(gpointer user_data)
1604 char *address = NULL;
1605 address = (char*) user_data;
1606 bt_tds_activation_info *info = NULL;
1607 /* Indication:Fail*/
1608 unsigned char buffer[2] = {0x01, 0x04};
1610 BT_DBG("Activation timer Expired [Provider] [%s]", address);
1612 info = __bt_tds_activation_info_by_address(address);
1614 __bt_tds_send_indication_event(info, buffer, sizeof(buffer));
1618 int _bt_tds_activate_control_point(int request_id, char *sender, bluetooth_device_address_t *dev_addr,
1619 char *handle, unsigned char *param, int length)
1622 GVariantBuilder *builder1;
1624 GVariantBuilder *builder2;
1627 bt_tds_activation_info *info = NULL;
1628 GDBusConnection *conn;
1629 char *address = NULL;
1632 BT_CHECK_PARAMETER(handle, return);
1633 BT_CHECK_PARAMETER(sender, return);
1634 BT_CHECK_PARAMETER(dev_addr, return);
1635 BT_CHECK_PARAMETER(param, return);
1637 conn = _bt_gdbus_get_system_gconn();
1638 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1640 BT_DBG("TDS Control point Activate handle [%s] data length [%d]", handle, length);
1641 /* Check if activation is ongoing for the same Remote Provider */
1642 address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1643 _bt_convert_addr_type_to_string(address, dev_addr->addr);
1645 info = __bt_tds_activation_info_by_address(address);
1646 if (info && info->activation_timeout_id > 0) {
1647 BT_ERR("Activation is already ongoing in remote provider");
1649 return BLUETOOTH_ERROR_IN_PROGRESS;
1652 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1654 for (i = 0; i < length; i++)
1655 g_variant_builder_add(builder1, "y", param[i]);
1657 val = g_variant_new("ay", builder1);
1659 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1661 g_variant_builder_add(builder2, "{sv}", "offset",
1662 g_variant_new_uint16(offset));
1664 options = g_variant_new("a{sv}", builder2);
1666 /* Activate Control Point */
1667 g_dbus_connection_call(conn,
1670 GATT_CHAR_INTERFACE,
1672 g_variant_new("(@ay@a{sv})",
1675 G_DBUS_CALL_FLAGS_NONE,
1677 (GAsyncReadyCallback)__bluetooth_internal_activation_request_cb,
1680 g_variant_builder_unref(builder1);
1681 g_variant_builder_unref(builder2);
1684 info = g_malloc0(sizeof(bt_tds_activation_info));
1685 info->remote_address = g_strdup(address);
1686 info->sender = g_strdup(sender);
1687 tds_activation_info_list = g_slist_append(tds_activation_info_list, info);
1689 info->req_id = request_id;
1690 info->activation_timeout_id = g_timeout_add(BT_TRANSPORT_ACTIVATION_TIMEOUT_MAX,
1691 (GSourceFunc)__bt_tds_indication_timeout_cb, (gpointer)info->remote_address);
1694 return BLUETOOTH_ERROR_NONE;
1697 static bt_tds_activation_info* __bt_tds_activation_info_by_address(char *address)
1700 bt_tds_activation_info *info = NULL;
1702 for (l = tds_activation_info_list; l != NULL; l = g_slist_next(l)) {
1703 info = (bt_tds_activation_info*)l->data;
1707 if (!g_strcmp0(info->remote_address, address)) {
1708 BT_INFO("Seeker found waiting for Ind from Provider addr[%s]",
1709 info->remote_address);
1716 static bt_tds_data_read_req_info* __bt_tds_data_read_info_by_address(char *address)
1719 bt_tds_data_read_req_info *info = NULL;
1721 for (l = tds_data_read_req_info_list; l != NULL; l = g_slist_next(l)) {
1722 info = (bt_tds_data_read_req_info*)l->data;
1726 if (!g_strcmp0(info->remote_address, address)) {
1727 BT_INFO("Found waiting for Transport Data Read from Provider addr[%s]",
1728 info->remote_address);
1735 static void __bt_tds_remove_indication_info(bt_tds_activation_info *info)
1737 BT_DBG("Removing Indication Info [%s]", info->remote_address);
1739 tds_activation_info_list = g_slist_remove(tds_activation_info_list, info);
1740 if (info->remote_address)
1741 g_free(info->remote_address);
1743 g_free(info->sender);
1744 if (info->activation_timeout_id > 0) {
1745 g_source_remove(info->activation_timeout_id);
1746 info->activation_timeout_id = 0;
1751 static void __bt_tds_remove_data_read_req_info(bt_tds_data_read_req_info *info)
1753 BT_DBG("Removing Read Req Info [%s]", info->remote_address);
1755 tds_data_read_req_info_list = g_slist_remove(tds_data_read_req_info_list, info);
1756 if (info->remote_address)
1757 g_free(info->remote_address);
1759 g_free(info->sender);
1763 static void __bt_tds_send_indication_event(bt_tds_activation_info *info,
1764 unsigned char *buffer, int len)
1769 tds_data = g_variant_new_from_data((const GVariantType *)"ay",
1770 buffer, len, TRUE, NULL, NULL);
1772 BT_DBG("Send Indication event to sender");
1773 param = g_variant_new("(s@ay)", info->remote_address, tds_data);
1774 _bt_send_event_to_dest(info->sender, BT_TDS_EVENT,
1775 BLUETOOTH_EVENT_TDS_ACTIVATION_INDICATION,
1778 /* Remove info from list */
1779 __bt_tds_remove_indication_info(info);
1782 void _bt_tds_check_indication(const char *path, GVariant *msg)
1784 char address[BT_ADDRESS_STRING_SIZE] = {0};
1785 bt_tds_activation_info *info = NULL;
1786 unsigned char *buffer = NULL;
1789 GVariant *value = NULL;
1792 _bt_convert_device_path_to_address(path, address);
1793 info = __bt_tds_activation_info_by_address(address);
1796 g_variant_get(msg, "(is@ay)", NULL, NULL, &value);
1797 len = g_variant_get_size(value);
1798 BT_DBG("Indication data from Provider len[%d]", len);
1800 buffer = (unsigned char *)g_variant_get_data(value);
1802 for (i = 0; i < len; i++)
1803 BT_DBG("%.2x", buffer[i]);
1807 if (info->activation_timeout_id > 0)
1808 g_source_remove(info->activation_timeout_id);
1810 /* Send Indication & info removed internally */
1811 __bt_tds_send_indication_event(info, buffer, len);
1813 g_variant_unref(value);