[TDS] Modify ReadValue and WriteValue API's
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-tds.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  *              http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 #include <glib.h>
19 #include <gio/gio.h>
20 #include <dlog.h>
21 #include <string.h>
22 #include <syspopup_caller.h>
23 #include <vconf.h>
24 #include <bundle_internal.h>
25
26 #include "bluetooth-api.h"
27 #include "bt-internal-types.h"
28
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"
35
36 #define GATT_SERV_INTERFACE             "org.bluez.GattService1"
37 #define GATT_CHAR_INTERFACE             "org.bluez.GattCharacteristic1"
38 #define GATT_DESC_INTERFACE             "org.bluez.GattDescriptor1"
39
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 */
43
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
49
50 #define BT_ADV_FLAG_LEN 3
51 #define TDS_DATA_LEN_MAX        1024
52 #define NUM_TDS_PROVIDER_MAX    10
53
54 typedef enum {
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;
59
60 typedef enum {
61         TDS_ROLE_UNSPECIFIED = 0,
62         TDS_ROLE_SEEKER,
63         TDS_ROLE_PROVIDER,
64         TDS_ROLE_SEEKER_PROVIDER
65 } bt_tds_role_t;
66
67 typedef enum {
68         TRANSPORT_DATA_COMPLETE,
69         TRANSPORT_DATA_INCOMPLETE
70 } bt_tds_transport_data_state_t;
71
72 typedef struct {
73         unsigned int tds_handle;
74         bt_tds_role_t role;
75         bluetooth_tds_transport_t transport;
76         bluetooth_tds_transport_state_t state;
77         unsigned int data_len;
78         unsigned char *data;
79 } bt_tds_transport_info_t;
80
81 typedef struct {
82         char *sender;
83         int adv_handle;
84         unsigned int manuf_data_len;
85         unsigned char *manuf_data;
86         GSList *transports;
87 } bt_tds_provider_t;
88
89 /* TDS Activation Request structure */
90 typedef struct {
91         char *remote_address;
92         char *sender;
93         unsigned int activation_timeout_id;
94         int req_id;
95 } bt_tds_activation_info;
96
97 /* TDS transport specific data read Request info structure */
98 typedef struct {
99         char *remote_address;
100         char *sender;
101         int req_id;
102 } bt_tds_data_read_req_info;
103
104 GSList *provider_list = NULL;
105 static int assigned_adv_handle;
106 static gboolean adv_handle_used[NUM_TDS_PROVIDER_MAX];
107
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;
111
112 static GSList *tds_activation_info_list = NULL;
113 static GSList *tds_data_read_req_info_list = NULL;
114
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);
121
122 static void __bt_init_adv_handle(void)
123 {
124         assigned_adv_handle = 0;
125         memset(adv_handle_used, 0x00, NUM_TDS_PROVIDER_MAX);
126 }
127
128 static int __bt_provider_get_adv_handle(void)
129 {
130         int index;
131
132         index = assigned_adv_handle + 1;
133
134         if (index >= NUM_TDS_PROVIDER_MAX)
135                 index = 0;
136
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");
141                         return -1;
142                 }
143
144                 index++;
145
146                 if (index >= NUM_TDS_PROVIDER_MAX)
147                         index = 0;
148         }
149
150         assigned_adv_handle = index;
151         adv_handle_used[index] = TRUE;
152
153         return assigned_adv_handle;
154 }
155
156 static void __bt_provider_delete_adv_handle(int handle)
157 {
158         ret_if(handle >= NUM_TDS_PROVIDER_MAX);
159         ret_if(handle < 0);
160
161         adv_handle_used[handle] = FALSE;
162 }
163
164 static unsigned char __bt_tds_get_organization_id(int transport)
165 {
166         BT_INFO("transport: %d", transport);
167
168         switch (transport) {
169         case BLUETOOTH_TDS_TRANSPORT_BT:
170                 return 0x01;
171         case BLUETOOTH_TDS_TRANSPORT_CUSTOM:
172                 return 0x02;
173         default:
174                 BT_ERR("Invaid transport");
175                 return 0x00;
176         }
177 }
178
179 static int __bt_tds_get_transport(unsigned char org_id)
180 {
181         BT_INFO("org_id: %d", org_id);
182
183         switch (org_id) {
184         case 0x01:
185                 return BLUETOOTH_TDS_TRANSPORT_BT;
186         case 0x02:
187                 return BLUETOOTH_TDS_TRANSPORT_CUSTOM;
188         default:
189                 BT_ERR("Invaid org_id");
190                 return BLUETOOTH_TDS_TRANSPORT_INVALID;
191         }
192 }
193
194 static unsigned char __bt_tds_set_role(unsigned char flag, bt_tds_role_t role)
195 {
196
197         BT_INFO("Flag: %.2X, Role: %d", flag, role);
198
199         switch (role) {
200         case TDS_ROLE_UNSPECIFIED:
201                 flag = flag & 0xFC;
202                 break;
203         case TDS_ROLE_SEEKER:
204                 flag = flag & 0xFC;
205                 flag = flag | 0x01;
206                 break;
207         case TDS_ROLE_PROVIDER:
208                 flag = flag & 0xFC;
209                 flag = flag | 0x02;
210                 break;
211         case TDS_ROLE_SEEKER_PROVIDER:
212                 flag = flag & 0xFC;
213                 flag = flag | 0x03;
214                 break;
215         default:
216                 BT_ERR("Invalid role received");
217         }
218
219         return flag;
220 }
221
222 static int __bt_tds_get_role(unsigned char flag)
223 {
224
225         BT_INFO("Flag: %.2X", flag);
226
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;
233         else
234                 return TDS_ROLE_UNSPECIFIED;
235 }
236
237 static unsigned char __bt_tds_set_transport_data_incomplete(
238                 unsigned char flag, gboolean state)
239 {
240         BT_INFO("Flag: %.2X, Data state: %d", flag, state);
241
242         if (state)
243                 flag = flag | 0x04; /* Set incomplete bit to 1 */
244         else
245                 flag = flag & 0xFB; /* Set incomplete bit to 0 */
246
247         return flag;
248 }
249
250 static unsigned char __bt_tds_set_transport_state(
251                 unsigned char flag, bluetooth_tds_transport_state_t state)
252 {
253         BT_INFO("Flag: %.2X, Transport state: %d", flag, state);
254
255         switch (state) {
256         case BLUETOOTH_TDS_TRANSPORT_STATE_OFF:
257                 flag = flag & 0xE7;
258                 break;
259         case BLUETOOTH_TDS_TRANSPORT_STATE_ON:
260                 flag = flag & 0xE7;
261                 flag = flag | 0x08;
262                 break;
263         case BLUETOOTH_TDS_TRANSPORT_STATE_UNAVAILABLE:
264                 flag = flag & 0xE7;
265                 flag = flag | 0x10;
266                 break;
267         case BLUETOOTH_TDS_TRANSPORT_STATE_RESERVED:
268                 flag = flag & 0xE7;
269                 flag = flag | 0x18;
270                 break;
271         default:
272                 BT_ERR("Invalid transport state received");
273         }
274
275         return flag;
276 }
277
278 static unsigned char __bt_tds_get_activation_response_code(int result)
279 {
280         unsigned char resp;
281
282         switch (result) {
283         case BLUETOOTH_ERROR_NONE:
284                 resp = TDS_CONTROL_POINT_RESPONSE_SUCCESS; /* Success */
285                 break;
286         case BLUETOOTH_ERROR_INVALID_PARAM:
287                 resp = TDS_CONTROL_POINT_RESPONSE_INVALID_PARAMETER; /*Invalid Parameter */
288                 break;
289         case BLUETOOTH_ERROR_NOT_SUPPORT:
290                 resp = TDS_CONTROL_POINT_RESPONSE_UNSUPPORTED_ORG_ID; /* Unsupported Organization ID*/
291                 break;
292         case BLUETOOTH_ERROR_INTERNAL:
293                 resp = TDS_CONTROL_POINT_RESPONSE_OPERATION_FAILED; /* */
294                 break;
295         default:
296                 BT_INFO("Unknown response code: %d received", result);
297                 resp = TDS_CONTROL_POINT_RESPONSE_OPERATION_FAILED;
298         }
299
300         return resp;
301 }
302
303 static bt_tds_provider_t* __bt_tds_provider_find_from_list(const char *sender)
304 {
305         GSList *l;
306
307         retv_if(NULL == sender, NULL);
308
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))
312                         return provider;
313         }
314
315         return NULL;
316 }
317
318 static unsigned char* __bt_tds_provider_get_tds_blocks(unsigned int *length)
319 {
320         GSList *l;
321         GSList *l1;
322         unsigned int len = 0;
323         unsigned char data[TDS_DATA_LEN_MAX];
324
325         retv_if(NULL == length, NULL);
326
327         for (l = provider_list; NULL != l; l = g_slist_next(l)) {
328                 bt_tds_provider_t *provider = l->data;
329
330                 if (!provider)
331                         continue;
332
333                 for (l1 = provider->transports; l1 != NULL; l1 = g_slist_next(l1)) {
334                         bt_tds_transport_info_t *transport_info = l1->data;
335
336                         if (!transport_info || !transport_info->data)
337                                 continue;
338
339                         if (len + transport_info->data_len > sizeof(data)) {
340                                 BT_ERR("Could not set complete the tds data, size exceeded");
341                                 break;
342                         }
343
344                         memcpy(&(data[len]), transport_info->data, transport_info->data_len);
345                         len += transport_info->data_len;
346                 }
347         }
348
349         *length = len;
350         BT_INFO("length = %d", *length);
351         return g_memdup(data, *length);
352 }
353
354 static void __bt_tds_set_scan_resp_data(bt_tds_provider_t *provider)
355 {
356         bluetooth_scan_resp_data_t scan_resp;
357         char *name = "bt-service";
358         int adv_handle = 0;
359         int len = 0;
360         int ret;
361
362         BT_DBG("+");
363
364         if (provider) {
365                 name = provider->sender;
366                 adv_handle = provider->adv_handle;
367
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;
373                 }
374         } else {
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;
380                 }
381         }
382
383         if (len <= (BLUETOOTH_SCAN_RESP_DATA_LENGTH_MAX - 2)) {
384                 /* Include name */
385                 scan_resp.data[len++] = 1;
386                 scan_resp.data[len++] = BT_AD_TYPE_LOCAL_NAME;
387         }
388
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);
392
393         BT_DBG("-");
394 }
395
396 /*
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.
400  */
401 static int __bt_tds_provider_get_tds_adv_data(bt_tds_provider_t *provider, guint8 *adv_data)
402 {
403         GSList *l;
404         GSList *l1;
405         unsigned int len = 0;
406         unsigned int max_adv_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - BT_ADV_FLAG_LEN;
407         int transport;
408
409         retv_if(NULL == provider, -1);
410         retv_if(NULL == adv_data, -1);
411
412         adv_data[1] = 0x26;
413         len = 2;
414
415         for (transport = BLUETOOTH_TDS_TRANSPORT_BT;
416                         transport < BLUETOOTH_TDS_TRANSPORT_INVALID; transport++) {
417                 gboolean flag = FALSE;
418
419                 if (len > max_adv_len - 3)
420                         break;
421
422                 for (l = provider_list; l != NULL; l = g_slist_next(l)) {
423                         bt_tds_provider_t *provider = l->data;
424
425                         if (!provider)
426                                 continue;
427
428                         for (l1 = provider->transports; l1 != NULL; l1 = g_slist_next(l1)) {
429                                 bt_tds_transport_info_t *transport_info = l1->data;
430
431                                 if (!transport_info || !transport_info->data ||
432                                                 transport_info->transport != transport)
433                                         continue;
434
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 */
439                                 flag = true;
440                                 break;
441                         }
442
443                         if (flag)
444                                 break;
445                 }
446         }
447
448         BT_INFO("len = %d", len);
449         if (len <= 2)
450                 return -1; /* No data */
451
452         adv_data[0] = len - 1;
453         return len;
454 }
455
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)
458 {
459         GSList *l;
460         unsigned int len = 0;
461         unsigned int max_adv_len = BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX - BT_ADV_FLAG_LEN;
462         int count;
463
464         retv_if(NULL == provider, -1);
465         retv_if(NULL == adv_data, -1);
466
467         count = g_slist_length(provider->transports);
468         adv_data[1] = 0x26;
469         len = 2;
470
471         for (l = provider->transports; l != NULL; l = g_slist_next(l)) {
472                 bt_tds_transport_info_t *transport_info = l->data;
473
474                 if (!transport_info || !transport_info->data)
475                         continue;
476
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;
481                 } else {
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 */
487                         break;
488                 }
489
490                 count--;
491         }
492
493         BT_INFO("len = %d", len);
494         if (len <= 2)
495                 return -1; /* No data */
496
497         adv_data[0] = len - 1;
498         return len;
499 }
500
501 static int __bt_tds_set_advertising(bt_tds_provider_t *provider)
502 {
503         bluetooth_advertising_data_t adv;
504         bluetooth_advertising_params_t param;
505         char *name = "bt-service";
506         int adv_handle = 0;
507         int length;
508         int ret;
509         int i;
510
511         BT_DBG("+");
512
513         if (provider) {
514                 name = provider->sender;
515                 adv_handle = provider->adv_handle;
516
517                 /* Get updated TDS advertising data */
518                 length = __bt_tds_provider_get_tds_multi_adv_data(provider, adv.data);
519                 if (0 == length)
520                         BT_INFO("No adv data found, return");
521         } else {
522                 /* No provider is present, no need to enable advertising */
523                 if (0 == g_slist_length(provider_list))
524                         return BLUETOOTH_ERROR_NONE;
525
526                 /* Get updated TDS advertising data */
527                 length = __bt_tds_provider_get_tds_adv_data(provider, adv.data);
528                 if (0 == length)
529                         BT_INFO("No adv data found, return");
530         }
531
532         /* If length <= 0, no need to start advertisement */
533         if (0 >= length)
534                 return BLUETOOTH_ERROR_NONE;
535
536         for (i = 0; i < length; i++)
537                 BT_DBG("adv_data: %.2X", adv.data[i]);
538
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);
542                 return ret;
543         }
544
545         /* set scan response data */
546         __bt_tds_set_scan_resp_data(provider);
547
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;
552
553         ret = _bt_set_custom_advertising(name, adv_handle, TRUE, &param, FALSE);
554         if (ret != BLUETOOTH_ERROR_NONE) {
555                 BT_ERR("Failed to enable advertising with error: %d", ret);
556                 return ret;
557         }
558
559         BT_DBG("-");
560         return BLUETOOTH_ERROR_NONE;
561 }
562
563 static int __bt_tds_disable_advertising(bt_tds_provider_t *provider)
564 {
565         char *name = "bt-service";
566         int adv_handle = 0;
567         int ret;
568
569         BT_DBG("+");
570
571         if (provider) {
572                 name = provider->sender;
573                 adv_handle = provider->adv_handle;
574         }
575
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);
583                         return ret;
584                 }
585         }
586
587         BT_DBG("-");
588         return BLUETOOTH_ERROR_NONE;
589 }
590
591 static int __bt_tds_provider_update_transport_data(bt_tds_provider_t *provider)
592 {
593         GDBusProxy *proxy;
594         GDBusConnection *conn;
595         char *adapter_path = NULL;
596         GError *error = NULL;
597         GVariant *result = NULL;
598         GVariantBuilder *builder;
599         GVariant *temp;
600         unsigned char *buf = NULL;
601         unsigned int length = 0;
602         int i;
603
604         BT_DBG("+");
605
606         conn = _bt_gdbus_get_system_gconn();
607         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
608
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;
613         }
614
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);
621
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]);
628         g_free(buf);
629
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,
635                         NULL, &error);
636         g_object_unref(proxy);
637         if (result == NULL) {
638                 if (error != NULL) {
639                         BT_ERR("Error occured in Proxy call [%s]\n", error->message);
640                         g_error_free(error);
641                 } else {
642                         BT_ERR("Error occured in Proxy call: SetData");
643                 }
644                 return BLUETOOTH_ERROR_INTERNAL;
645         }
646
647         BT_DBG("-");
648         return BLUETOOTH_ERROR_NONE;
649 }
650
651 static void __bt_free_tds_transport_info(gpointer data, gpointer user_data)
652 {
653         bt_tds_transport_info_t *transport_info = data;
654
655         ret_if(NULL == transport_info);
656
657         BT_DBG("+");
658
659         g_free(transport_info->data);
660         g_free(transport_info);
661
662         BT_DBG("-");
663 }
664
665 static bt_tds_transport_info_t * __bt_tds_find_transport_info(
666                 bt_tds_provider_t *provider, unsigned int handle)
667 {
668         GSList *l;
669
670         retv_if(!provider, NULL);
671
672         for (l = provider->transports; l != NULL; l = g_slist_next(l)) {
673                 bt_tds_transport_info_t *transport_info = l->data;
674
675                 if (!transport_info)
676                         continue;
677
678                 if (transport_info->tds_handle == handle)
679                         return transport_info;
680         }
681
682         return NULL;
683 }
684
685 int _bt_tds_provider_register(const char *sender)
686 {
687         GDBusProxy *proxy;
688         GDBusConnection *conn;
689         char *adapter_path = NULL;
690         GError *error = NULL;
691         GVariant *result = NULL;
692         bt_tds_provider_t *provider;
693
694         retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM);
695
696         BT_DBG("+");
697
698         if (__bt_tds_provider_find_from_list(sender))
699                 return BLUETOOTH_ERROR_ALREADY_INITIALIZED;
700
701         if (0 == g_slist_length(provider_list)) {
702                 /* Init adv_handle list */
703                 __bt_init_adv_handle();
704
705                 conn = _bt_gdbus_get_system_gconn();
706                 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
707
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;
712                 }
713
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);
720
721                 result = g_dbus_proxy_call_sync(proxy, "RegisterTdsProvider",
722                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1,
723                                 NULL, &error);
724                 g_object_unref(proxy);
725                 if (result == NULL) {
726                         if (error != NULL) {
727                                 BT_ERR("Error occured in Proxy call [%s]", error->message);
728                                 g_error_free(error);
729                         } else {
730                                 BT_ERR("Error occured in Proxy call: RegisterTdsProvider");
731                         }
732                         return BLUETOOTH_ERROR_INTERNAL;
733                 }
734         }
735
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);
741                 g_free(provider);
742                 return BLUETOOTH_ERROR_INTERNAL;
743         }
744
745         provider_list = g_slist_append(provider_list, provider);
746
747         BT_DBG("-");
748         return BLUETOOTH_ERROR_NONE;
749 }
750
751 int _bt_tds_provider_unregister(const char *sender)
752 {
753         GDBusProxy *proxy;
754         GDBusConnection *conn;
755         char *adapter_path = NULL;
756         GError *error = NULL;
757         GVariant *result = NULL;
758         bt_tds_provider_t *provider = NULL;
759         int ret;
760
761         retv_if(NULL == sender, BLUETOOTH_ERROR_NOT_INITIALIZED);
762
763         BT_DBG("+");
764
765         provider = __bt_tds_provider_find_from_list(sender);
766         if (!provider)
767                 return BLUETOOTH_ERROR_NOT_INITIALIZED;
768
769         if (1 == g_slist_length(provider_list)) {
770                 conn = _bt_gdbus_get_system_gconn();
771                 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
772
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;
777                 }
778
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);
783
784                 g_free(adapter_path);
785                 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
786
787                 result = g_dbus_proxy_call_sync(proxy, "UnregisterTdsProvider",
788                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1,
789                                 NULL, &error);
790                 g_object_unref(proxy);
791                 if (result == NULL) {
792                         if (error != NULL) {
793                                 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
794                                 g_error_free(error);
795                         } else {
796                                 BT_ERR("Error occured in Proxy call: UnregisterTdsProvider");
797                         }
798                         return BLUETOOTH_ERROR_INTERNAL;
799                 }
800         }
801
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);
807         } else {
808                 /*
809                  * Disable advertising here. Later on receiving advertising disabled event,
810                  * advertising will be enabled again with updated advertising data
811                  */
812                 ret = __bt_tds_disable_advertising(NULL);
813                 if (ret != BLUETOOTH_ERROR_NONE)
814                         BT_ERR("Failed to disable advertising with error: %d", ret);
815         }
816
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);
822         g_free(provider);
823
824         BT_DBG("-");
825         return BLUETOOTH_ERROR_NONE;
826 }
827
828 int _bt_tds_provider_transport_create(const char *sender, int transport, unsigned int tds_handle)
829 {
830         bt_tds_transport_info_t *transport_info;
831         bt_tds_provider_t *provider = NULL;
832
833         retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM);
834
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;
839         }
840
841         BT_DBG("+");
842
843         provider = __bt_tds_provider_find_from_list(sender);
844         if (!provider)
845                 return BLUETOOTH_ERROR_NOT_INITIALIZED;
846
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);
853
854         BT_DBG("-");
855         return BLUETOOTH_ERROR_NONE;
856 }
857
858 int _bt_tds_provider_transport_remove(const char *sender, unsigned int tds_handle)
859 {
860         bt_tds_provider_t *provider = NULL;
861         bt_tds_transport_info_t *transport_info;
862         int ret;
863
864         retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM);
865
866         BT_DBG("+");
867
868         provider = __bt_tds_provider_find_from_list(sender);
869         if (!provider)
870                 return BLUETOOTH_ERROR_INVALID_PARAM;
871
872         transport_info = __bt_tds_find_transport_info(provider, tds_handle);
873         if (!transport_info)
874                 return BLUETOOTH_ERROR_INVALID_PARAM;
875
876         provider->transports = g_slist_remove(provider->transports, transport_info);
877         __bt_free_tds_transport_info(transport_info, NULL);
878
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);
883                 return ret;
884         }
885
886         /*
887          * Disable advertising here. Later on receiving advertising disabled event,
888          * advertising will be enabled again with updated advertising data.
889          */
890         if (_bt_is_multi_adv_supported())
891                 ret = __bt_tds_disable_advertising(provider);
892         else
893                 ret = __bt_tds_disable_advertising(NULL);
894         if (ret != BLUETOOTH_ERROR_NONE) {
895                 BT_ERR("Failed to enable advertising with error: %d", ret);
896                 return ret;
897         }
898
899         BT_DBG("-");
900         return BLUETOOTH_ERROR_NONE;
901 }
902
903 int _bt_tds_provider_set_manuf_data(char *sender, unsigned char *data, unsigned int len)
904 {
905         bt_tds_provider_t *provider;
906         int ret;
907
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);
911
912         BT_DBG("+");
913
914         BT_INFO("sender: %s", sender);
915         provider = __bt_tds_provider_find_from_list(sender);
916         if (!provider)
917                 return BLUETOOTH_ERROR_INVALID_PARAM;
918
919         /*
920          * Set manufacturer data and disable advertising here. Later on receiving advertising
921          * disabled event, advertising will be enabled again with updated advertising data.
922          */
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);
928
929                 ret = __bt_tds_disable_advertising(provider);
930         } else {
931                 manuf_data_len = len;
932                 memcpy(manuf_data, data, len);
933                 ret = __bt_tds_disable_advertising(NULL);
934         }
935         if (ret != BLUETOOTH_ERROR_NONE) {
936                 BT_ERR("Failed to enable advertising with error: %d", ret);
937                 return ret;
938         }
939
940         BT_DBG("-");
941         return BLUETOOTH_ERROR_NONE;
942 }
943
944 int _bt_tds_provider_set_transport_data(char *sender, int tds_handle,
945                 int transport_state, unsigned char *data, unsigned int len)
946 {
947         bt_tds_provider_t *provider;
948         bt_tds_transport_info_t *transport_info;
949         int ret;
950
951         retv_if(NULL == sender, BLUETOOTH_ERROR_INVALID_PARAM);
952         retv_if(len > 0 && NULL == data, BLUETOOTH_ERROR_INVALID_PARAM);
953
954         BT_DBG("+");
955
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;
960         }
961
962         BT_INFO("sender: %s, tds_handle: %X", sender, tds_handle);
963         provider = __bt_tds_provider_find_from_list(sender);
964         if (!provider)
965                 return BLUETOOTH_ERROR_INVALID_PARAM;
966
967         transport_info = __bt_tds_find_transport_info(provider, tds_handle);
968         if (!transport_info)
969                 return BLUETOOTH_ERROR_INVALID_PARAM;
970
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);
977         /* TDS block flag */
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);
985
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);
990                 return ret;
991         }
992
993         /*
994          * Disable advertising here. Later on receiving advertising disabled event,
995          * advertising will be enabled again with updated advertising data.
996          */
997         if (_bt_is_multi_adv_supported())
998                 ret = __bt_tds_disable_advertising(provider);
999         else
1000                 ret = __bt_tds_disable_advertising(NULL);
1001         if (ret != BLUETOOTH_ERROR_NONE) {
1002                 BT_ERR("Failed to enable advertising with error: %d", ret);
1003                 return ret;
1004         }
1005
1006         BT_DBG("-");
1007         return BLUETOOTH_ERROR_NONE;
1008 }
1009
1010 static int __bt_tds_send_activation_response(char *address,
1011                 unsigned char response, unsigned char *data, unsigned int len)
1012 {
1013         GDBusProxy *proxy;
1014         GDBusConnection *conn;
1015         char *device_path;
1016         GError *error = NULL;
1017         GVariant *result = NULL;
1018         GVariantBuilder *builder;
1019         GVariant *temp;
1020         int i;
1021
1022         retv_if(NULL == address, BLUETOOTH_ERROR_INVALID_PARAM);
1023         retv_if(NULL == data, BLUETOOTH_ERROR_INVALID_PARAM);
1024
1025         BT_DBG("+");
1026         conn = _bt_gdbus_get_system_gconn();
1027         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1028
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;
1033         }
1034
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);
1041
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]);
1045
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,
1051                         NULL, &error);
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);
1057                 } else {
1058                         BT_ERR("Error occured in Proxy call: SetData");
1059                 }
1060                 return BLUETOOTH_ERROR_INTERNAL;
1061         }
1062
1063         BT_DBG("-");
1064         return BLUETOOTH_ERROR_NONE;
1065 }
1066
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)
1069 {
1070         bt_tds_provider_t *provider;
1071         bt_tds_transport_info_t *transport_info;
1072         unsigned char resp;
1073         char addr[BT_ADDRESS_STRING_SIZE];
1074         int ret;
1075
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);
1079
1080         BT_DBG("+");
1081
1082         BT_INFO("sender: %s, tds_handle: 0x%X", sender, tds_handle);
1083         provider = __bt_tds_provider_find_from_list(sender);
1084         if (!provider)
1085                 return BLUETOOTH_ERROR_NOT_INITIALIZED;
1086
1087         transport_info = __bt_tds_find_transport_info(provider, tds_handle);
1088         if (!transport_info)
1089                 return BLUETOOTH_ERROR_INVALID_PARAM;
1090
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);
1096         }
1097
1098         _bt_convert_addr_type_to_string(addr, address->addr);
1099         resp = __bt_tds_get_activation_response_code(response);
1100
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);
1104                 return ret;
1105         }
1106
1107         BT_DBG("-");
1108         return BLUETOOTH_ERROR_NONE;
1109 }
1110
1111 void _bt_tds_handle_activation_request(const char *path,
1112                 unsigned char org_id, unsigned char *buf, int len)
1113 {
1114         int transport;
1115         char *address = NULL;
1116         GVariant *tds_data;
1117         GVariant *param;
1118         int count = 0;
1119         GSList *l;
1120         GSList *l1;
1121
1122         ret_if(NULL == path);
1123         ret_if(len > 0 && NULL == buf);
1124
1125         BT_DBG("+");
1126
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);
1131
1132         if (BLUETOOTH_TDS_TRANSPORT_INVALID == transport)
1133                 goto err;
1134
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);
1138
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;
1142
1143                 if (!provider)
1144                         continue;
1145
1146                 for (l1 = provider->transports; l1 != NULL; l1 = g_slist_next(l1)) {
1147                         bt_tds_transport_info_t *transport_info = l1->data;
1148
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);
1152                                 count++;
1153                         }
1154                 }
1155         }
1156
1157         /* If no provider found for transport type, send error */
1158         if (0 == count)
1159                 goto err;
1160
1161         g_free(address);
1162
1163         BT_DBG("-");
1164         return;
1165 err:
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);
1169         g_free(address);
1170 }
1171
1172 void _bt_tds_stop_by_terminated_process(char *name)
1173 {
1174         bt_tds_provider_t *provider = NULL;
1175
1176         provider = __bt_tds_provider_find_from_list(name);
1177         if (!provider)
1178                 return;
1179
1180         _bt_tds_provider_unregister(provider->sender);
1181 }
1182
1183 void _bt_tds_handle_adv_disabled(const char *sender, int adv_handle)
1184 {
1185         bt_tds_provider_t *provider = NULL;
1186
1187         BT_INFO("sender: %s, adv_handle:%d", sender, adv_handle);
1188
1189         ret_if(NULL == sender);
1190
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");
1195                         return;
1196                 }
1197         } else {
1198                 if (adv_handle != 0)
1199                         return;
1200         }
1201
1202         __bt_tds_set_advertising(provider);
1203 }
1204
1205 static void __bt_tds_transport_data_read_desc_cb(GObject *source_object,
1206                         GAsyncResult *res, gpointer user_data)
1207 {
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;
1214         guint8 g_byte;
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;
1220         int k;
1221
1222         GVariant *var_data, *param = NULL;
1223         char *tds_data = NULL;
1224         char *address;
1225
1226         BT_DBG("+");
1227         system_gconn = _bt_gdbus_get_system_gconn();
1228
1229         address = (char *)user_data;
1230         info = __bt_tds_data_read_info_by_address(address);
1231
1232         value = g_dbus_connection_call_finish(system_gconn, res, &error);
1233
1234         if (error) {
1235                 BT_ERR("Error : %s \n", error->message);
1236                 if (info) {
1237                         req_info = _bt_get_request_info(info->req_id);
1238                         __bt_tds_remove_data_read_req_info(info);
1239                 }
1240                 result = BLUETOOTH_ERROR_INTERNAL;
1241                 goto dbus_return;
1242         }
1243
1244         gp_byte_array = g_byte_array_new();
1245         g_variant_get(value, "(ay)", &iter);
1246
1247         while (g_variant_iter_loop(iter, "y",  &g_byte))
1248                 g_byte_array_append(gp_byte_array, &g_byte, 1);
1249
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;
1253         }
1254
1255         tds_data = (char *)g_memdup(att_value.val, att_value.val_len);
1256
1257         var_data = g_variant_new_from_data((const GVariantType *)"ay",
1258                         tds_data, att_value.val_len, TRUE, NULL, NULL);
1259
1260         if (info) {
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,
1264                                 param);
1265                 req_info = _bt_get_request_info(info->req_id);
1266                 __bt_tds_remove_data_read_req_info(info);
1267         }
1268
1269         /* DEBUG */
1270         for (k = 0; k < att_value.val_len; k++)
1271                 BT_DBG("Transport Data[%d] = [0x%x]", k, att_value.val[k]);
1272
1273 dbus_return:
1274         if (req_info == NULL) {
1275                 BT_ERR("TDS Complete data read Request is not found!!");
1276                 goto done;
1277         }
1278
1279         if (req_info->context == NULL)
1280                 goto done;
1281
1282         _bt_convert_addr_string_to_type(device_addr.addr,
1283                         (const char *)address);
1284
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));
1289
1290         _bt_delete_request_list(req_info->req_id);
1291
1292 done:
1293         /* Data free */
1294         if (error)
1295                 g_clear_error(&error);
1296         if (gp_byte_array)
1297                 g_byte_array_free(gp_byte_array, TRUE);
1298         if (address)
1299                 g_free(address);
1300         if (value)
1301                 g_variant_unref(value);
1302         if (iter)
1303                 g_variant_iter_free(iter);
1304         if (tds_data)
1305                 g_free(tds_data);
1306         BT_DBG("-");
1307 }
1308
1309 int _bt_tds_read_transport_data(int request_id, char *sender,
1310                 bluetooth_device_address_t *dev_addr, char *handle)
1311 {
1312         GDBusConnection *conn;
1313         char *address = NULL;
1314         bt_tds_data_read_req_info *info = NULL;
1315         GVariantBuilder *builder = NULL;
1316         guint16 offset = 0;
1317
1318         BT_CHECK_PARAMETER(handle, return);
1319         BT_CHECK_PARAMETER(sender, return);
1320         BT_CHECK_PARAMETER(dev_addr, return);
1321
1322         conn = _bt_gdbus_get_system_gconn();
1323         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1324
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);
1328
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);
1332                 g_free(address);
1333                 return BLUETOOTH_ERROR_IN_PROGRESS;
1334         }
1335
1336         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1337         /*offset*/
1338         g_variant_builder_add(builder, "{sv}", "offset",
1339                         g_variant_new("q", offset));
1340
1341         g_dbus_connection_call(conn, BT_BLUEZ_NAME, handle,
1342                         GATT_DESC_INTERFACE,
1343                         "ReadValue",
1344                         g_variant_new("(a{sv})", builder),
1345                         G_VARIANT_TYPE("(ay)"),
1346                         G_DBUS_CALL_FLAGS_NONE,
1347                         -1,
1348                         NULL,
1349                         (GAsyncReadyCallback)__bt_tds_transport_data_read_desc_cb,
1350                         (gpointer)address);
1351
1352         g_variant_builder_unref(builder);
1353
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);
1360
1361         BT_DBG("-");
1362         return BLUETOOTH_ERROR_NONE;
1363 }
1364
1365 static void __bluetooth_internal_control_point_enable_request_cb(GObject *source_object,
1366                         GAsyncResult *res, gpointer user_data)
1367 {
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} };
1378         BT_DBG("+");
1379
1380         system_gconn = _bt_gdbus_get_system_gconn();
1381         value = g_dbus_connection_call_finish(system_gconn, res, &error);
1382
1383         if (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;
1396                 else
1397                         result = BLUETOOTH_ERROR_INTERNAL;
1398         } else {
1399                 BT_DBG("TDS CCCD enable request successful, send event to BT App");
1400         }
1401
1402         address = (char *)user_data;
1403         info = __bt_tds_activation_info_by_address(address);
1404
1405         if (info)
1406                 req_info = _bt_get_request_info(info->req_id);
1407
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");
1411                 /* Reset Timer */
1412                 if (info->activation_timeout_id > 0) {
1413                         g_source_remove(info->activation_timeout_id);
1414                         info->activation_timeout_id = 0;
1415                 }
1416
1417                 /* Remove Indication Info */
1418                 __bt_tds_remove_indication_info(info);
1419         } else {
1420                 /* CCCD Enable Request successful */
1421                 if (info) {
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,
1425                                         param);
1426                 }
1427         }
1428
1429         if (req_info == NULL) {
1430                 BT_ERR("TDS Control Point CCCD Enable Request is not found!!");
1431                 goto done;
1432         }
1433
1434         if (req_info->context == NULL)
1435                 goto done;
1436
1437         _bt_convert_addr_string_to_type(device_addr.addr,
1438                         (const char *)address);
1439
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));
1444
1445         _bt_delete_request_list(req_info->req_id);
1446
1447 done:
1448         if (value)
1449                 g_variant_unref(value);
1450         if (error)
1451                 g_clear_error(&error);
1452         if (address)
1453                 g_free(address);
1454
1455         BT_DBG("-");
1456         return;
1457 }
1458
1459 int _bt_tds_enable_control_point(int request_id, char *sender, bluetooth_device_address_t *dev_addr,
1460                         char *handle)
1461 {
1462         GDBusConnection *conn;
1463         char *address = NULL;
1464         bt_tds_activation_info *info = NULL;
1465
1466         BT_CHECK_PARAMETER(handle, return);
1467         BT_CHECK_PARAMETER(sender, return);
1468         BT_CHECK_PARAMETER(dev_addr, return);
1469
1470         conn = _bt_gdbus_get_system_gconn();
1471         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1472
1473         BT_DBG("TDS Control point CCCD Handle [%s]", handle);
1474
1475         address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1476         _bt_convert_addr_type_to_string(address, dev_addr->addr);
1477
1478         if (__bt_tds_activation_info_by_address(address) != NULL) {
1479                 BT_ERR("Activation is already ongoing for same remote provider");
1480                 g_free(address);
1481                 return BLUETOOTH_ERROR_IN_PROGRESS;
1482         }
1483
1484         BT_INFO("Start Notify to Bluez");
1485         g_dbus_connection_call(conn,
1486                         BT_BLUEZ_NAME,
1487                         handle,
1488                         GATT_CHAR_INTERFACE,
1489                         "StartNotify",
1490                         NULL,
1491                         NULL,
1492                         G_DBUS_CALL_FLAGS_NONE,
1493                         GATT_DEFAULT_TIMEOUT, NULL,
1494                         (GAsyncReadyCallback)__bluetooth_internal_control_point_enable_request_cb,
1495                         (gpointer)address);
1496
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);
1502
1503         BT_DBG("-");
1504         return BLUETOOTH_ERROR_NONE;
1505 }
1506
1507 static int __bluetooth_get_att_error_code(GError *error)
1508 {
1509         int att_ecode = 0;
1510         int len;
1511         char *str = NULL;
1512
1513         BT_ERR("Error : %s", error->message);
1514         str = g_strrstr(error->message, "ATT error: 0x");
1515         if (str) {
1516                 len = strlen(str);
1517                 att_ecode =  g_ascii_xdigit_value(str[len-2]) << 4;
1518                 att_ecode += g_ascii_xdigit_value(str[len-1]);
1519         } else
1520                 return BLUETOOTH_ATT_ERROR_INTERNAL;
1521
1522         return att_ecode;
1523 }
1524
1525 static void __bluetooth_internal_activation_request_cb(GObject *source_object,
1526                         GAsyncResult *res, gpointer user_data)
1527 {
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} };
1538         BT_DBG("+");
1539
1540         system_gconn = _bt_gdbus_get_system_gconn();
1541         value = g_dbus_connection_call_finish(system_gconn, res, &error);
1542
1543         if (error)
1544                 result = __bluetooth_get_att_error_code(error);
1545
1546         address = (char *)user_data;
1547         info = __bt_tds_activation_info_by_address(address);
1548         if (info)
1549                 req_info = _bt_get_request_info(info->req_id);
1550
1551         /* Is Activation request failed for any reason, reset timer */
1552         if (result != BLUETOOTH_ERROR_NONE && info != NULL) {
1553                 BT_ERR("Activation Request failed");
1554                 /* Reset Timer */
1555                 if (info->activation_timeout_id > 0) {
1556                         g_source_remove(info->activation_timeout_id);
1557                         info->activation_timeout_id = 0;
1558                 }
1559
1560                 /* Remove Indication Info */
1561                 __bt_tds_remove_indication_info(info);
1562         } else {
1563                 /* Activation Request successful */
1564                 if (info) {
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,
1568                                         param);
1569                 }
1570         }
1571
1572         if (req_info == NULL) {
1573                 BT_ERR("TDS Control Point Activation Request is not found!!");
1574                 goto done;
1575         }
1576
1577         if (req_info->context == NULL)
1578                 goto done;
1579
1580         _bt_convert_addr_string_to_type(device_addr.addr,
1581                         (const char *)address);
1582
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));
1587
1588         _bt_delete_request_list(req_info->req_id);
1589
1590 done:
1591         if (value)
1592                 g_variant_unref(value);
1593         if (error)
1594                 g_clear_error(&error);
1595         if (address)
1596                 g_free(address);
1597
1598         BT_DBG("-");
1599         return;
1600 }
1601
1602 static bool __bt_tds_indication_timeout_cb(gpointer user_data)
1603 {
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};
1609
1610         BT_DBG("Activation timer Expired [Provider] [%s]", address);
1611
1612         info = __bt_tds_activation_info_by_address(address);
1613         if (info)
1614                 __bt_tds_send_indication_event(info, buffer, sizeof(buffer));
1615         return FALSE;
1616 }
1617
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)
1620 {
1621         GVariant *val;
1622         GVariantBuilder *builder1;
1623         GVariant *options;
1624         GVariantBuilder *builder2;
1625         guint16 offset = 0;
1626         int i;
1627         bt_tds_activation_info *info = NULL;
1628         GDBusConnection *conn;
1629         char *address = NULL;
1630         BT_DBG("+");
1631
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);
1636
1637         conn = _bt_gdbus_get_system_gconn();
1638         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1639
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);
1644
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");
1648                 g_free(address);
1649                 return BLUETOOTH_ERROR_IN_PROGRESS;
1650         }
1651
1652         builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1653
1654         for (i = 0; i < length; i++)
1655                 g_variant_builder_add(builder1, "y", param[i]);
1656
1657         val = g_variant_new("ay", builder1);
1658
1659         builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1660         /*offset*/
1661         g_variant_builder_add(builder2, "{sv}", "offset",
1662                         g_variant_new_uint16(offset));
1663
1664         options = g_variant_new("a{sv}", builder2);
1665
1666         /* Activate Control Point */
1667         g_dbus_connection_call(conn,
1668                         BT_BLUEZ_NAME,
1669                         handle,
1670                         GATT_CHAR_INTERFACE,
1671                         "WriteValue",
1672                         g_variant_new("(@ay@a{sv})",
1673                                 val, options),
1674                         NULL,
1675                         G_DBUS_CALL_FLAGS_NONE,
1676                         -1, NULL,
1677                         (GAsyncReadyCallback)__bluetooth_internal_activation_request_cb,
1678                         (gpointer)address);
1679
1680         g_variant_builder_unref(builder1);
1681         g_variant_builder_unref(builder2);
1682
1683         if (info == NULL) {
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);
1688         }
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);
1692
1693         BT_DBG("-");
1694         return BLUETOOTH_ERROR_NONE;
1695 }
1696
1697 static bt_tds_activation_info* __bt_tds_activation_info_by_address(char *address)
1698 {
1699         GSList *l;
1700         bt_tds_activation_info *info = NULL;
1701
1702         for (l = tds_activation_info_list; l != NULL; l = g_slist_next(l)) {
1703                 info = (bt_tds_activation_info*)l->data;
1704                 if (info == NULL)
1705                         continue;
1706
1707                 if (!g_strcmp0(info->remote_address, address)) {
1708                         BT_INFO("Seeker found waiting for Ind from Provider addr[%s]",
1709                                         info->remote_address);
1710                         return info;
1711                 }
1712         }
1713         return NULL;
1714 }
1715
1716 static bt_tds_data_read_req_info* __bt_tds_data_read_info_by_address(char *address)
1717 {
1718         GSList *l;
1719         bt_tds_data_read_req_info *info = NULL;
1720
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;
1723                 if (info == NULL)
1724                         continue;
1725
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);
1729                         return info;
1730                 }
1731         }
1732         return NULL;
1733 }
1734
1735 static void __bt_tds_remove_indication_info(bt_tds_activation_info *info)
1736 {
1737         BT_DBG("Removing Indication Info [%s]", info->remote_address);
1738
1739         tds_activation_info_list = g_slist_remove(tds_activation_info_list, info);
1740         if (info->remote_address)
1741                 g_free(info->remote_address);
1742         if (info->sender)
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;
1747         }
1748         g_free(info);
1749 }
1750
1751 static void __bt_tds_remove_data_read_req_info(bt_tds_data_read_req_info *info)
1752 {
1753         BT_DBG("Removing Read Req Info [%s]", info->remote_address);
1754
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);
1758         if (info->sender)
1759                 g_free(info->sender);
1760         g_free(info);
1761 }
1762
1763 static void __bt_tds_send_indication_event(bt_tds_activation_info *info,
1764                                                 unsigned char *buffer, int len)
1765 {
1766         GVariant *tds_data;
1767         GVariant *param;
1768
1769         tds_data = g_variant_new_from_data((const GVariantType *)"ay",
1770                         buffer, len, TRUE, NULL, NULL);
1771
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,
1776                                         param);
1777
1778         /* Remove info from list */
1779         __bt_tds_remove_indication_info(info);
1780 }
1781
1782 void _bt_tds_check_indication(const char *path, GVariant *msg)
1783 {
1784         char address[BT_ADDRESS_STRING_SIZE] = {0};
1785         bt_tds_activation_info *info = NULL;
1786         unsigned char *buffer = NULL;
1787         int len = 0;
1788         int i;
1789         GVariant *value = NULL;
1790         BT_DBG("+");
1791
1792         _bt_convert_device_path_to_address(path, address);
1793         info = __bt_tds_activation_info_by_address(address);
1794
1795         if (info) {
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);
1799                 if (len > 0) {
1800                         buffer = (unsigned char *)g_variant_get_data(value);
1801                         /* DEBUG */
1802                         for (i = 0; i < len; i++)
1803                                 BT_DBG("%.2x", buffer[i]);
1804                 }
1805
1806                 /* Reset Timer */
1807                 if (info->activation_timeout_id > 0)
1808                         g_source_remove(info->activation_timeout_id);
1809
1810                 /* Send Indication & info removed internally */
1811                 __bt_tds_send_indication_event(info, buffer, len);
1812
1813                 g_variant_unref(value);
1814         }
1815         BT_DBG("-");
1816 }