[Bluetooth][OTP] Add base code for OTP server role
[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                 g_free(address);
1237                 if (info) {
1238                         req_info = _bt_get_request_info(info->req_id);
1239                         __bt_tds_remove_data_read_req_info(info);
1240                 }
1241                 result = BLUETOOTH_ERROR_INTERNAL;
1242                 goto dbus_return;
1243         }
1244
1245         gp_byte_array = g_byte_array_new();
1246         g_variant_get(value, "(ay)", &iter);
1247
1248         while (g_variant_iter_loop(iter, "y",  &g_byte))
1249                 g_byte_array_append(gp_byte_array, &g_byte, 1);
1250
1251         if (gp_byte_array->len != 0) {
1252                 att_value.val_len = (unsigned int)gp_byte_array->len;
1253                 att_value.val = (unsigned char *)gp_byte_array->data;
1254         }
1255
1256         tds_data = (char *)g_memdup(att_value.val, att_value.val_len);
1257
1258         var_data = g_variant_new_from_data((const GVariantType *)"ay",
1259                         tds_data, att_value.val_len, TRUE, NULL, NULL);
1260
1261         if (info) {
1262                 param = g_variant_new("(isn@ay)", result, address, att_value.val_len, var_data);
1263                 _bt_send_event_to_dest(info->sender, BT_TDS_EVENT,
1264                                 BLUETOOTH_EVENT_TDS_TRANSPORT_DATA_RECEIVED,
1265                                 param);
1266                 req_info = _bt_get_request_info(info->req_id);
1267                 __bt_tds_remove_data_read_req_info(info);
1268         }
1269
1270         /* DEBUG */
1271         for (k = 0; k < att_value.val_len; k++)
1272                 BT_DBG("Transport Data[%d] = [0x%x]", k, att_value.val[k]);
1273
1274 dbus_return:
1275         if (req_info == NULL) {
1276                 BT_ERR("TDS Complete data read Request is not found!!");
1277                 goto done;
1278         }
1279
1280         if (req_info->context == NULL)
1281                 goto done;
1282
1283         _bt_convert_addr_string_to_type(device_addr.addr,
1284                         (const char *)address);
1285
1286         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
1287                         &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
1288         g_dbus_method_invocation_return_value(req_info->context,
1289                         g_variant_new("(iv)", result, out_param1));
1290
1291         _bt_delete_request_list(req_info->req_id);
1292
1293 done:
1294         /* Data free */
1295         if (error)
1296                 g_clear_error(&error);
1297         if (gp_byte_array)
1298                 g_byte_array_free(gp_byte_array, TRUE);
1299         if (address)
1300                 g_free(address);
1301         if (value)
1302                 g_variant_unref(value);
1303         if (iter)
1304                 g_variant_iter_free(iter);
1305         if (tds_data)
1306                 g_free(tds_data);
1307         BT_DBG("-");
1308 }
1309
1310 int _bt_tds_read_transport_data(int request_id, char *sender,
1311                 bluetooth_device_address_t *dev_addr, char *handle)
1312 {
1313         GDBusConnection *conn;
1314         char *address = NULL;
1315         bt_tds_data_read_req_info *info = NULL;
1316
1317         BT_CHECK_PARAMETER(handle, return);
1318         BT_CHECK_PARAMETER(sender, return);
1319         BT_CHECK_PARAMETER(dev_addr, return);
1320
1321         conn = _bt_gdbus_get_system_gconn();
1322         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1323
1324         BT_DBG("Read Complete TDS block from Provider [Handle] [%s]", handle);
1325         address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1326         _bt_convert_addr_type_to_string(address, dev_addr->addr);
1327
1328         /* If TDS data read already pending on same Provider, then return In progress */
1329         if (__bt_tds_data_read_info_by_address(address) != NULL) {
1330                 BT_ERR("TDS Data Read Req is ongoing in remote provider [%s]", address);
1331                 g_free(address);
1332                 return BLUETOOTH_ERROR_IN_PROGRESS;
1333         }
1334
1335         g_dbus_connection_call(conn,
1336                         BT_BLUEZ_NAME,
1337                         handle,
1338                         GATT_DESC_INTERFACE,
1339                         "ReadValue",
1340                         NULL,
1341                         G_VARIANT_TYPE("(ay)"),
1342                         G_DBUS_CALL_FLAGS_NONE,
1343                         -1,
1344                         NULL,
1345                         (GAsyncReadyCallback)__bt_tds_transport_data_read_desc_cb,
1346                         (gpointer)address);
1347
1348         /* Save Info in pending list */
1349         info = g_malloc0(sizeof(bt_tds_data_read_req_info));
1350         info->remote_address = g_strdup(address);
1351         info->sender = g_strdup(sender);
1352         info->req_id = request_id;
1353         tds_data_read_req_info_list = g_slist_append(tds_data_read_req_info_list, info);
1354
1355         BT_DBG("-");
1356         return BLUETOOTH_ERROR_NONE;
1357 }
1358
1359 static void __bluetooth_internal_control_point_enable_request_cb(GObject *source_object,
1360                         GAsyncResult *res, gpointer user_data)
1361 {
1362         GError *error = NULL;
1363         GDBusConnection *system_gconn = NULL;
1364         GVariant *value = NULL;
1365         GVariant *param = NULL;
1366         GVariant *out_param1 = NULL;
1367         int result = BLUETOOTH_ERROR_NONE;
1368         char *address = NULL;
1369         bt_tds_activation_info *info = NULL;
1370         request_info_t *req_info = NULL;
1371         bluetooth_device_address_t device_addr = { {0} };
1372         BT_DBG("+");
1373
1374         system_gconn = _bt_gdbus_get_system_gconn();
1375         value = g_dbus_connection_call_finish(system_gconn, res, &error);
1376
1377         if (error) {
1378                 BT_ERR("Error : %s \n", error->message);
1379                 if (g_strrstr(error->message, "Already notifying"))
1380                         result = BLUETOOTH_ERROR_NONE;
1381                 else if (g_strrstr(error->message, "In Progress"))
1382                         result = BLUETOOTH_ERROR_IN_PROGRESS;
1383                 else if (g_strrstr(error->message, "Operation is not supported"))
1384                         result = BLUETOOTH_ERROR_NOT_SUPPORT;
1385                 else if (g_strrstr(error->message, "Write not permitted") ||
1386                                 g_strrstr(error->message, "Operation Not Authorized"))
1387                         result = BLUETOOTH_ERROR_PERMISSION_DEINED;
1388                 else if (g_strrstr(error->message, "Not paired"))
1389                         result = BLUETOOTH_ERROR_NOT_PAIRED;
1390                 else
1391                         result = BLUETOOTH_ERROR_INTERNAL;
1392         } else {
1393                 BT_DBG("TDS CCCD enable request successful, send event to BT App");
1394         }
1395
1396         address = (char *)user_data;
1397         info = __bt_tds_activation_info_by_address(address);
1398
1399         if (info)
1400                 req_info = _bt_get_request_info(info->req_id);
1401
1402         /* If CCCD Enable request failed for any reason, reset timer */
1403         if (result != BLUETOOTH_ERROR_NONE && info != NULL) {
1404                 BT_ERR("Activation Request failed");
1405                 /* Reset Timer */
1406                 if (info->activation_timeout_id > 0) {
1407                         g_source_remove(info->activation_timeout_id);
1408                         info->activation_timeout_id = 0;
1409                 }
1410
1411                 /* Remove Indication Info */
1412                 __bt_tds_remove_indication_info(info);
1413         } else {
1414                 /* CCCD Enable Request successful */
1415                 if (info) {
1416                         param = g_variant_new("(is)", result, address);
1417                         _bt_send_event_to_dest(info->sender, BT_TDS_EVENT,
1418                                         BLUETOOTH_EVENT_TDS_CONTROL_POINT_ENABLED,
1419                                         param);
1420                 }
1421         }
1422
1423         if (req_info == NULL) {
1424                 BT_ERR("TDS Control Point CCCD Enable Request is not found!!");
1425                 goto done;
1426         }
1427
1428         if (req_info->context == NULL)
1429                 goto done;
1430
1431         _bt_convert_addr_string_to_type(device_addr.addr,
1432                         (const char *)address);
1433
1434         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
1435                         &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
1436         g_dbus_method_invocation_return_value(req_info->context,
1437                         g_variant_new("(iv)", result, out_param1));
1438
1439         _bt_delete_request_list(req_info->req_id);
1440
1441 done:
1442         if (value)
1443                 g_variant_unref(value);
1444         if (error)
1445                 g_clear_error(&error);
1446         if (address)
1447                 g_free(address);
1448
1449         BT_DBG("-");
1450         return;
1451 }
1452
1453 int _bt_tds_enable_control_point(int request_id, char *sender, bluetooth_device_address_t *dev_addr,
1454                         char *handle)
1455 {
1456         GDBusConnection *conn;
1457         char *address = NULL;
1458         bt_tds_activation_info *info = NULL;
1459
1460         BT_CHECK_PARAMETER(handle, return);
1461         BT_CHECK_PARAMETER(sender, return);
1462         BT_CHECK_PARAMETER(dev_addr, return);
1463
1464         conn = _bt_gdbus_get_system_gconn();
1465         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1466
1467         BT_DBG("TDS Control point CCCD Handle [%s]", handle);
1468
1469         address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1470         _bt_convert_addr_type_to_string(address, dev_addr->addr);
1471
1472         if (__bt_tds_activation_info_by_address(address) != NULL) {
1473                 BT_ERR("Activation is already ongoing for same remote provider");
1474                 g_free(address);
1475                 return BLUETOOTH_ERROR_IN_PROGRESS;
1476         }
1477
1478         BT_INFO("Start Notify to Bluez");
1479         g_dbus_connection_call(conn,
1480                         BT_BLUEZ_NAME,
1481                         handle,
1482                         GATT_CHAR_INTERFACE,
1483                         "StartNotify",
1484                         NULL,
1485                         NULL,
1486                         G_DBUS_CALL_FLAGS_NONE,
1487                         GATT_DEFAULT_TIMEOUT, NULL,
1488                         (GAsyncReadyCallback)__bluetooth_internal_control_point_enable_request_cb,
1489                         (gpointer)address);
1490
1491         info = g_malloc0(sizeof(bt_tds_activation_info));
1492         info->remote_address = g_strdup(address);
1493         info->sender = g_strdup(sender);
1494         info->req_id = request_id;
1495         tds_activation_info_list = g_slist_append(tds_activation_info_list, info);
1496
1497         BT_DBG("-");
1498         return BLUETOOTH_ERROR_NONE;
1499 }
1500
1501 static void __bluetooth_internal_activation_request_cb(GObject *source_object,
1502                         GAsyncResult *res, gpointer user_data)
1503 {
1504         GError *error = NULL;
1505         GDBusConnection *system_gconn = NULL;
1506         GVariant *value = NULL;
1507         GVariant *param = NULL;
1508         GVariant *out_param1 = NULL;
1509         int result = BLUETOOTH_ERROR_NONE;
1510         guint8 att_ecode = 0;
1511         char *address = NULL;
1512         bt_tds_activation_info *info = NULL;
1513         request_info_t *req_info = NULL;
1514         bluetooth_device_address_t device_addr = { {0} };
1515         BT_DBG("+");
1516
1517         system_gconn = _bt_gdbus_get_system_gconn();
1518         value = g_dbus_connection_call_finish(system_gconn, res, &error);
1519
1520         if (error) {
1521                 BT_ERR("Error : %s \n", error->message);
1522                 result = BLUETOOTH_ERROR_INTERNAL;
1523         } else {
1524                 g_variant_get(value, "(y)", &att_ecode);
1525                 if (att_ecode) {
1526                         result =  BLUETOOTH_ERROR_INTERNAL;
1527                         BT_ERR("ATT Error code: %d \n", att_ecode);
1528                 }
1529         }
1530
1531         address = (char *)user_data;
1532         info = __bt_tds_activation_info_by_address(address);
1533         if (info)
1534                 req_info = _bt_get_request_info(info->req_id);
1535
1536         /* Is Activation request failed for any reason, reset timer */
1537         if (result != BLUETOOTH_ERROR_NONE && info != NULL) {
1538                 BT_ERR("Activation Request failed");
1539                 /* Reset Timer */
1540                 if (info->activation_timeout_id > 0) {
1541                         g_source_remove(info->activation_timeout_id);
1542                         info->activation_timeout_id = 0;
1543                 }
1544
1545                 /* Remove Indication Info */
1546                 __bt_tds_remove_indication_info(info);
1547         } else {
1548                 /* Activation Request successful */
1549                 if (info) {
1550                         param = g_variant_new("(is)", result, address);
1551                         _bt_send_event_to_dest(info->sender, BT_TDS_EVENT,
1552                                         BLUETOOTH_EVENT_TDS_ACTIVATION_RESULT,
1553                                         param);
1554                 }
1555         }
1556
1557         if (req_info == NULL) {
1558                 BT_ERR("TDS Control Point Activation Request is not found!!");
1559                 goto done;
1560         }
1561
1562         if (req_info->context == NULL)
1563                 goto done;
1564
1565         _bt_convert_addr_string_to_type(device_addr.addr,
1566                         (const char *)address);
1567
1568         out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
1569                         &device_addr, sizeof(bluetooth_device_address_t), TRUE, NULL, NULL);
1570         g_dbus_method_invocation_return_value(req_info->context,
1571                         g_variant_new("(iv)", result, out_param1));
1572
1573         _bt_delete_request_list(req_info->req_id);
1574
1575 done:
1576         if (value)
1577                 g_variant_unref(value);
1578         if (error)
1579                 g_clear_error(&error);
1580         if (address)
1581                 g_free(address);
1582
1583         BT_DBG("-");
1584         return;
1585 }
1586
1587 static bool __bt_tds_indication_timeout_cb(gpointer user_data)
1588 {
1589         char *address = NULL;
1590         address = (char*) user_data;
1591         bt_tds_activation_info *info = NULL;
1592         /* Indication:Fail*/
1593         unsigned char buffer[2] = {0x01, 0x04};
1594
1595         BT_DBG("Activation timer Expired [Provider] [%s]", address);
1596
1597         info = __bt_tds_activation_info_by_address(address);
1598         if (info)
1599                 __bt_tds_send_indication_event(info, buffer, sizeof(buffer));
1600         return FALSE;
1601 }
1602
1603 int _bt_tds_activate_control_point(int request_id, char *sender, bluetooth_device_address_t *dev_addr,
1604                                         char *handle, unsigned char *param, int length)
1605 {
1606         GVariant *val;
1607         GVariantBuilder *builder;
1608         int i;
1609         bt_tds_activation_info *info = NULL;
1610         GDBusConnection *conn;
1611         char *address = NULL;
1612         BT_DBG("+");
1613
1614         BT_CHECK_PARAMETER(handle, return);
1615         BT_CHECK_PARAMETER(sender, return);
1616         BT_CHECK_PARAMETER(dev_addr, return);
1617         BT_CHECK_PARAMETER(param, return);
1618
1619         conn = _bt_gdbus_get_system_gconn();
1620         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1621
1622         BT_DBG("TDS Control point Activate handle [%s] data length [%d]", handle, length);
1623         /* Check if activation is ongoing for the same Remote Provider */
1624         address = g_malloc0(BT_ADDRESS_STRING_SIZE);
1625         _bt_convert_addr_type_to_string(address, dev_addr->addr);
1626
1627         info = __bt_tds_activation_info_by_address(address);
1628         if (info && info->activation_timeout_id > 0) {
1629                 BT_ERR("Activation is already ongoing in remote provider");
1630                 g_free(address);
1631                 return BLUETOOTH_ERROR_IN_PROGRESS;
1632         }
1633
1634         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1635
1636         for (i = 0; i < length; i++)
1637                 g_variant_builder_add(builder, "y", param[i]);
1638
1639         val = g_variant_new("(ay)", builder);
1640
1641         /* Activate Control Point */
1642         g_dbus_connection_call(conn,
1643                         BT_BLUEZ_NAME,
1644                         handle,
1645                         GATT_CHAR_INTERFACE,
1646                         "WriteValue",
1647                         val,
1648                         G_VARIANT_TYPE("(y)"),
1649                         G_DBUS_CALL_FLAGS_NONE,
1650                         -1, NULL,
1651                         (GAsyncReadyCallback)__bluetooth_internal_activation_request_cb,
1652                         (gpointer)address);
1653
1654         g_variant_builder_unref(builder);
1655
1656         if (info == NULL) {
1657                 info = g_malloc0(sizeof(bt_tds_activation_info));
1658                 info->remote_address = g_strdup(address);
1659                 info->sender = g_strdup(sender);
1660                 tds_activation_info_list = g_slist_append(tds_activation_info_list, info);
1661         }
1662         info->req_id = request_id;
1663         info->activation_timeout_id = g_timeout_add(BT_TRANSPORT_ACTIVATION_TIMEOUT_MAX,
1664                         (GSourceFunc)__bt_tds_indication_timeout_cb, (gpointer)info->remote_address);
1665
1666         BT_DBG("-");
1667         return BLUETOOTH_ERROR_NONE;
1668 }
1669
1670 static bt_tds_activation_info* __bt_tds_activation_info_by_address(char *address)
1671 {
1672         GSList *l;
1673         bt_tds_activation_info *info = NULL;
1674
1675         for (l = tds_activation_info_list; l != NULL; l = g_slist_next(l)) {
1676                 info = (bt_tds_activation_info*)l->data;
1677                 if (info == NULL)
1678                         continue;
1679
1680                 if (!g_strcmp0(info->remote_address, address)) {
1681                         BT_INFO("Seeker found waiting for Ind from Provider addr[%s]",
1682                                         info->remote_address);
1683                         return info;
1684                 }
1685         }
1686         return NULL;
1687 }
1688
1689 static bt_tds_data_read_req_info* __bt_tds_data_read_info_by_address(char *address)
1690 {
1691         GSList *l;
1692         bt_tds_data_read_req_info *info = NULL;
1693
1694         for (l = tds_data_read_req_info_list; l != NULL; l = g_slist_next(l)) {
1695                 info = (bt_tds_data_read_req_info*)l->data;
1696                 if (info == NULL)
1697                         continue;
1698
1699                 if (!g_strcmp0(info->remote_address, address)) {
1700                         BT_INFO("Found waiting for Transport Data Read from Provider addr[%s]",
1701                                         info->remote_address);
1702                         return info;
1703                 }
1704         }
1705         return NULL;
1706 }
1707
1708 static void __bt_tds_remove_indication_info(bt_tds_activation_info *info)
1709 {
1710         BT_DBG("Removing Indication Info [%s]", info->remote_address);
1711
1712         tds_activation_info_list = g_slist_remove(tds_activation_info_list, info);
1713         if (info->remote_address)
1714                 g_free(info->remote_address);
1715         if (info->sender)
1716                 g_free(info->sender);
1717         if (info->activation_timeout_id > 0) {
1718                 g_source_remove(info->activation_timeout_id);
1719                 info->activation_timeout_id = 0;
1720         }
1721         g_free(info);
1722 }
1723
1724 static void __bt_tds_remove_data_read_req_info(bt_tds_data_read_req_info *info)
1725 {
1726         BT_DBG("Removing Read Req Info [%s]", info->remote_address);
1727
1728         tds_data_read_req_info_list = g_slist_remove(tds_data_read_req_info_list, info);
1729         if (info->remote_address)
1730                 g_free(info->remote_address);
1731         if (info->sender)
1732                 g_free(info->sender);
1733         g_free(info);
1734 }
1735
1736 static void __bt_tds_send_indication_event(bt_tds_activation_info *info,
1737                                                 unsigned char *buffer, int len)
1738 {
1739         GVariant *tds_data;
1740         GVariant *param;
1741
1742         tds_data = g_variant_new_from_data((const GVariantType *)"ay",
1743                         buffer, len, TRUE, NULL, NULL);
1744
1745         BT_DBG("Send Indication event to sender");
1746         param = g_variant_new("(s@ay)", info->remote_address, tds_data);
1747         _bt_send_event_to_dest(info->sender, BT_TDS_EVENT,
1748                                         BLUETOOTH_EVENT_TDS_ACTIVATION_INDICATION,
1749                                         param);
1750
1751         /* Remove info from list */
1752         __bt_tds_remove_indication_info(info);
1753 }
1754
1755 void _bt_tds_check_indication(const char *path, GVariant *msg)
1756 {
1757         char address[BT_ADDRESS_STRING_SIZE] = {0};
1758         bt_tds_activation_info *info = NULL;
1759         unsigned char *buffer = NULL;
1760         int len = 0;
1761         int i;
1762         GVariant *value = NULL;
1763         BT_DBG("+");
1764
1765         _bt_convert_device_path_to_address(path, address);
1766         info = __bt_tds_activation_info_by_address(address);
1767
1768         if (info) {
1769                 g_variant_get(msg, "(is@ay)", NULL, NULL, &value);
1770                 len = g_variant_get_size(value);
1771                 BT_DBG("Indication data from Provider len[%d]", len);
1772                 if (len > 0) {
1773                         buffer = (unsigned char *)g_variant_get_data(value);
1774                         /* DEBUG */
1775                         for (i = 0; i < len; i++)
1776                                 BT_DBG("%.2x", buffer[i]);
1777                 }
1778
1779                 /* Reset Timer */
1780                 if (info->activation_timeout_id > 0)
1781                         g_source_remove(info->activation_timeout_id);
1782
1783                 /* Send Indication & info removed internally */
1784                 __bt_tds_send_indication_event(info, buffer, len);
1785
1786                 g_variant_unref(value);
1787         }
1788         BT_DBG("-");
1789 }