Merge branch 'master' into tizen_2.1
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-rfcomm-client.c
1 /*
2  * bluetooth-frwk
3  *
4  * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *              http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <dbus/dbus-glib.h>
21 #include <dbus/dbus.h>
22 #include <glib.h>
23 #include <dlog.h>
24 #include <string.h>
25 #include <fcntl.h>
26
27 #include "bluetooth-api.h"
28 #include "bt-internal-types.h"
29
30 #include "bt-service-common.h"
31 #include "bt-service-event.h"
32 #include "bt-service-util.h"
33 #include "bt-service-rfcomm-client.h"
34 #include "bt-service-rfcomm-server.h"
35
36 typedef struct {
37         int req_id;
38         char *channel;
39         char *address;
40         char *uuid;
41         DBusGProxy *rfcomm_proxy;
42 } rfcomm_function_data_t;
43
44 rfcomm_function_data_t *rfcomm_info;
45 GSList *client_list;
46
47 static bt_rfcomm_info_t *__bt_rfcomm_get_client_info(int socket_fd)
48 {
49         GSList *l;
50         bt_rfcomm_info_t *client_info;
51
52         for (l = client_list; l != NULL; l = l->next) {
53                 client_info = l->data;
54
55                 if (client_info == NULL)
56                         continue;
57
58                 if (socket_fd == client_info->fd)
59                         return client_info;
60         }
61
62         return NULL;
63 }
64
65 static int __bt_rfcomm_open_socket(char *dev_node)
66 {
67         int socket_fd;
68
69         socket_fd = open(dev_node, O_RDWR | O_NOCTTY);
70
71         if (socket_fd < 0) {
72                 BT_ERR("\nCan't open TTY : %s(%d)");
73                 return socket_fd;
74         }
75
76         BT_DBG("/dev/rfcomm fd = %d", socket_fd);
77
78         if (_bt_set_non_blocking_tty(socket_fd) < 0) {
79                 /* Even if setting the tty fails we will continue */
80                 BT_ERR("Unable to set /dev/rfcomm fd = %d", socket_fd);
81         }
82
83         return socket_fd;
84 }
85
86 static int __bt_rfcomm_disconnect_request(int socket_fd)
87 {
88         DBusGConnection *conn;
89         DBusGProxy *adapter_proxy;
90         DBusGProxy *rfcomm_proxy;
91         GError *error = NULL;
92         bt_rfcomm_info_t *client_info;
93         gchar *device_path = NULL;
94         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
95
96         retv_if(address == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
97
98         adapter_proxy = _bt_get_adapter_proxy();
99         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
100
101         conn = _bt_get_system_gconn();
102         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
103
104         client_info = __bt_rfcomm_get_client_info(socket_fd);
105         retv_if(client_info == NULL, BLUETOOTH_ERROR_INTERNAL);
106
107         dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
108                           G_TYPE_STRING, client_info->address, G_TYPE_INVALID,
109                           DBUS_TYPE_G_OBJECT_PATH, &device_path, G_TYPE_INVALID);
110
111         retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
112
113         rfcomm_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
114                                       device_path, BT_SERIAL_INTERFACE);
115
116         BT_DBG("device path: %s", device_path);
117         g_free(device_path);
118
119         retv_if(rfcomm_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
120
121         BT_DBG("device node: %s", client_info->dev_node);
122         if (!dbus_g_proxy_call(rfcomm_proxy, "Disconnect",
123                         &error,
124                         G_TYPE_STRING, client_info->dev_node,
125                         G_TYPE_INVALID, G_TYPE_INVALID)) {
126                 if (error) {
127                         BT_ERR("Disconnect Call Error, %s", error->message);
128                         g_error_free(error);
129                 }
130                 g_object_unref(rfcomm_proxy);
131                 return BLUETOOTH_ERROR_INTERNAL;
132         }
133         g_object_unref(rfcomm_proxy);
134
135         return BLUETOOTH_ERROR_NONE;
136 }
137
138 static int __bt_rfcomm_disconnect_cb(void *data)
139 {
140         int result = BLUETOOTH_ERROR_NONE;
141         bt_rfcomm_info_t *client_info = data;
142
143         retv_if(client_info == NULL, BLUETOOTH_ERROR_INTERNAL);
144
145         _bt_send_event(BT_RFCOMM_CLIENT_EVENT,
146                 BLUETOOTH_EVENT_RFCOMM_DISCONNECTED,
147                 DBUS_TYPE_INT32, &result,
148                 DBUS_TYPE_STRING, &client_info->address,
149                 DBUS_TYPE_STRING, &client_info->uuid,
150                 DBUS_TYPE_INT16, &client_info->fd,
151                 DBUS_TYPE_INVALID);
152
153         client_list = g_slist_remove(client_list, client_info);
154
155         g_source_remove(client_info->io_event);
156         close(client_info->fd);
157         g_free(client_info->dev_node);
158         g_free(client_info->address);
159         g_free(client_info->uuid);
160         g_free(client_info);
161
162         return BLUETOOTH_ERROR_NONE;
163 }
164
165 static int __bt_rfcomm_cancel_connect_cb(void *data)
166 {
167         int result = BLUETOOTH_ERROR_CANCEL_BY_USER;
168         bluetooth_rfcomm_connection_t conn_info;
169         request_info_t *req_info;
170         GArray *out_param1;
171         GArray *out_param2;
172
173         retv_if(rfcomm_info == NULL, BLUETOOTH_ERROR_INTERNAL);
174
175         req_info = _bt_get_request_info(rfcomm_info->req_id);
176
177         retv_if(req_info == NULL, BLUETOOTH_ERROR_INTERNAL);
178         retv_if(req_info->context == NULL, BLUETOOTH_ERROR_INTERNAL);
179
180         memset(&conn_info, 0x00, sizeof(bluetooth_rfcomm_connection_t));
181         conn_info.device_role = RFCOMM_ROLE_CLIENT;
182         g_strlcpy(conn_info.uuid, rfcomm_info->uuid,
183                                 BLUETOOTH_UUID_STRING_MAX);
184         conn_info.socket_fd = -1;
185         _bt_convert_addr_string_to_type(conn_info.device_addr.addr,
186                                         rfcomm_info->address);
187
188         out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
189         out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
190
191         g_array_append_vals(out_param1, &conn_info,
192                                         sizeof(bluetooth_rfcomm_connection_t));
193         g_array_append_vals(out_param2, &result, sizeof(int));
194
195         dbus_g_method_return(req_info->context, out_param1, out_param2);
196
197         g_array_free(out_param1, TRUE);
198         g_array_free(out_param2, TRUE);
199
200         _bt_delete_request_list(req_info->req_id);
201
202         g_object_unref(rfcomm_info->rfcomm_proxy);
203         g_free(rfcomm_info->address);
204         g_free(rfcomm_info->uuid);
205         g_free(rfcomm_info->channel);
206         g_free(rfcomm_info);
207         rfcomm_info = NULL;
208
209         return BLUETOOTH_ERROR_NONE;
210 }
211
212 static int __bt_rfcomm_terminate_client(int socket_fd)
213 {
214         BT_DBG("+");
215
216         int result;
217         bt_rfcomm_info_t *client_info;
218
219         client_info = __bt_rfcomm_get_client_info(socket_fd);
220         retv_if(client_info == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
221
222         result = __bt_rfcomm_disconnect_request(socket_fd);
223
224         if (result != BLUETOOTH_ERROR_NONE) {
225                 BT_ERR("Fail to disconnect socket");
226                 return result;
227         }
228
229         /* Send the disconnected event after return the function */
230         g_idle_add((GSourceFunc)__bt_rfcomm_disconnect_cb, client_info);
231
232         return BLUETOOTH_ERROR_NONE;
233 }
234
235 static gboolean __bt_rfcomm_client_data_received_cb(GIOChannel *chan,
236                                                         GIOCondition cond,
237                                                         gpointer data)
238 {
239         char *buffer = NULL;
240         gsize len;
241         int result = BLUETOOTH_ERROR_NONE;
242         bt_rfcomm_info_t *client_info = data;
243
244         BT_DBG("condition: %d", cond);
245
246         retv_if(client_info == NULL, FALSE);
247
248         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
249                 BT_ERR("Unix client disconnected (fd=%d)\n", client_info->fd);
250                 __bt_rfcomm_terminate_client(client_info->fd);
251                 return FALSE;
252         }
253
254         buffer = g_malloc0(BT_RFCOMM_BUFFER_MAX + 1);
255
256         if (g_io_channel_read_chars(chan, buffer, BT_RFCOMM_BUFFER_MAX,
257                                 &len, NULL) == G_IO_STATUS_ERROR) {
258                 BT_ERR("IO Channel read error client");
259                 g_free(buffer);
260                 __bt_rfcomm_terminate_client(client_info->fd);
261                 return FALSE;
262         }
263
264         if (len == 0) {
265                 BT_ERR("Read failed len=%d, fd=%d\n", len, client_info->fd);
266                 g_free(buffer);
267                 __bt_rfcomm_terminate_client(client_info->fd);
268                 return FALSE;
269         }
270
271         BT_DBG("%s  -  clientfd = %d", buffer, client_info->fd);
272
273         _bt_send_event(BT_RFCOMM_CLIENT_EVENT,
274                 BLUETOOTH_EVENT_RFCOMM_DATA_RECEIVED,
275                 DBUS_TYPE_INT32, &result,
276                 DBUS_TYPE_INT16, &client_info->fd,
277                 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
278                 &buffer, len,
279                 DBUS_TYPE_INVALID);
280
281         g_free(buffer);
282
283         return TRUE;
284 }
285
286 static void __bt_rfcomm_connected_cb(DBusGProxy *proxy, DBusGProxyCall *call,
287                                        gpointer user_data)
288 {
289         BT_DBG("+\n");
290         GError *err = NULL;
291         gchar *rfcomm_device_node;
292         int socket_fd = -1;
293         int result = BLUETOOTH_ERROR_NONE;
294         bt_rfcomm_info_t *client_info = NULL;
295         request_info_t *req_info;
296         bluetooth_rfcomm_connection_t conn_info;
297         GArray *out_param1;
298         GArray *out_param2;
299
300         dbus_g_proxy_end_call(proxy, call, &err,
301                         G_TYPE_STRING, &rfcomm_device_node, G_TYPE_INVALID);
302
303         g_object_unref(proxy);
304
305         if (rfcomm_info == NULL) {
306                 BT_ERR("rfcomm_info == NULL");
307                 goto done;
308         }
309
310         if (err != NULL) {
311                 BT_ERR("Error occured in connecting port [%s]", err->message);
312
313                 if (!strcmp("Host is down", err->message))
314                         result = BLUETOOTH_ERROR_HOST_DOWN;
315                 else
316                         result = BLUETOOTH_ERROR_CONNECTION_ERROR;
317
318                 goto dbus_return;
319         }
320
321         BT_DBG("Succss Connect REMOTE Device RFCOMM Node[%s]", rfcomm_device_node);
322
323         socket_fd = __bt_rfcomm_open_socket(rfcomm_device_node);
324
325         if (socket_fd < 0) {
326                 BT_ERR("Fail to open socket: %d", socket_fd);
327                 goto dbus_return;
328         }
329
330         client_info = g_malloc0(sizeof(bt_rfcomm_info_t));
331
332         client_info->fd = socket_fd;
333         client_info->dev_node = g_strdup(rfcomm_device_node);
334         client_info->address = g_strdup(rfcomm_info->address);
335         client_info->uuid = g_strdup(rfcomm_info->uuid);
336         client_info->io_channel = g_io_channel_unix_new(socket_fd);
337         client_info->io_event = g_io_add_watch(client_info->io_channel,
338                                 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
339                                 __bt_rfcomm_client_data_received_cb,
340                                 client_info);
341
342         g_io_channel_set_close_on_unref(client_info->io_channel, TRUE);
343         g_io_channel_set_flags(client_info->io_channel,
344                                 G_IO_FLAG_NONBLOCK, NULL);
345
346         client_list = g_slist_append(client_list, client_info);
347
348         _bt_send_event(BT_RFCOMM_CLIENT_EVENT,
349                 BLUETOOTH_EVENT_RFCOMM_CONNECTED,
350                 DBUS_TYPE_INT32, &result,
351                 DBUS_TYPE_STRING, &rfcomm_info->address,
352                 DBUS_TYPE_STRING, &rfcomm_info->uuid,
353                 DBUS_TYPE_INT16, &socket_fd,
354                 DBUS_TYPE_INVALID);
355
356 dbus_return:
357         req_info = _bt_get_request_info(rfcomm_info->req_id);
358
359         if (req_info == NULL || req_info->context == NULL)
360                 goto done;
361
362         memset(&conn_info, 0x00, sizeof(bluetooth_rfcomm_connection_t));
363         conn_info.device_role = RFCOMM_ROLE_CLIENT;
364         g_strlcpy(conn_info.uuid, rfcomm_info->uuid,
365                                 BLUETOOTH_UUID_STRING_MAX);
366
367         if (client_info)
368                 conn_info.socket_fd = client_info->fd;
369         else
370                 conn_info.socket_fd = -1;
371
372         _bt_convert_addr_string_to_type(conn_info.device_addr.addr,
373                                         rfcomm_info->address);
374
375         out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
376         out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
377
378         g_array_append_vals(out_param1, &conn_info,
379                                         sizeof(bluetooth_rfcomm_connection_t));
380         g_array_append_vals(out_param2, &result, sizeof(int));
381         dbus_g_method_return(req_info->context, out_param1, out_param2);
382
383         g_array_free(out_param1, TRUE);
384         g_array_free(out_param2, TRUE);
385         _bt_delete_request_list(req_info->req_id);
386 done:
387         if (err)
388                 g_error_free(err);
389
390         ret_if(rfcomm_info == NULL);
391
392         g_free(rfcomm_info->address);
393         g_free(rfcomm_info->uuid);
394         g_free(rfcomm_info->channel);
395         g_free(rfcomm_info);
396         rfcomm_info = NULL;
397 }
398
399 static void __bt_rfcomm_discover_services_cb(DBusGProxy *proxy, DBusGProxyCall *call,
400                                                     gpointer user_data)
401 {
402         GError *err = NULL;
403         GHashTable *hash = NULL;
404         const char *dev_path = NULL;
405         DBusGConnection *conn;
406         DBusGProxy *rfcomm_proxy;
407         int result = BLUETOOTH_ERROR_NONE;
408         GArray *out_param1;
409         GArray *out_param2;
410         request_info_t *req_info;
411         bluetooth_rfcomm_connection_t conn_info;
412
413         dbus_g_proxy_end_call(proxy, call, &err,
414                         dbus_g_type_get_map("GHashTable",
415                         G_TYPE_UINT, G_TYPE_STRING),
416                         &hash, G_TYPE_INVALID);
417
418         if (err != NULL) {
419                 BT_ERR("Error occured in Proxy call [%s]\n", err->message);
420                 result = BLUETOOTH_ERROR_CONNECTION_ERROR;
421                 g_error_free(err);
422                 goto fail;
423         }
424
425         g_hash_table_destroy(hash);
426
427         if (rfcomm_info == NULL) {
428                 result = BLUETOOTH_ERROR_INTERNAL;
429                 goto fail;
430         }
431
432         conn = _bt_get_system_gconn();
433         if (conn == NULL) {
434                 BT_ERR("ERROR: Can't get on system bus");
435                 result = BLUETOOTH_ERROR_INTERNAL;
436                 goto fail;
437         }
438
439         dev_path = dbus_g_proxy_get_path(proxy);
440
441         rfcomm_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
442                                                 dev_path,
443                                                 BT_SERIAL_INTERFACE);
444
445         g_object_unref(proxy);
446         proxy = NULL;
447
448         if (rfcomm_proxy == NULL) {
449                 BT_ERR("Failed to get the rfcomm proxy\n");
450                 result = BLUETOOTH_ERROR_SERVICE_NOT_FOUND;
451                 goto fail;
452         }
453
454         rfcomm_info->rfcomm_proxy = rfcomm_proxy;
455
456         if (!dbus_g_proxy_begin_call(rfcomm_proxy, "Connect",
457                         (DBusGProxyCallNotify)__bt_rfcomm_connected_cb,
458                         NULL,   /*user_data*/
459                         NULL,   /*destroy*/
460                         G_TYPE_STRING, rfcomm_info->uuid,
461                         G_TYPE_INVALID)) {
462                 BT_ERR("RFCOMM connect Dbus Call Error");
463                 g_object_unref(rfcomm_proxy);
464                 result = BLUETOOTH_ERROR_INTERNAL;
465                 goto fail;
466         }
467
468         BT_DBG("-\n");
469
470         return;
471 fail:
472         if (proxy)
473                 g_object_unref(proxy);
474
475         ret_if(rfcomm_info == NULL);
476
477         req_info = _bt_get_request_info(rfcomm_info->req_id);
478
479         if (req_info && req_info->context) {
480                 memset(&conn_info, 0x00, sizeof(bluetooth_rfcomm_connection_t));
481
482                 conn_info.device_role = RFCOMM_ROLE_CLIENT;
483                 g_strlcpy(conn_info.uuid, rfcomm_info->uuid,
484                                         BLUETOOTH_UUID_STRING_MAX);
485
486                 conn_info.socket_fd = -1;
487                 _bt_convert_addr_string_to_type(conn_info.device_addr.addr,
488                                                 rfcomm_info->address);
489
490                 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
491                 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
492
493                 g_array_append_vals(out_param1, &conn_info,
494                                                 sizeof(bluetooth_rfcomm_connection_t));
495                 g_array_append_vals(out_param2, &result, sizeof(int));
496
497                 dbus_g_method_return(req_info->context, out_param1, out_param2);
498
499                 g_array_free(out_param1, TRUE);
500                 g_array_free(out_param2, TRUE);
501                 _bt_delete_request_list(req_info->req_id);
502         }
503
504         g_free(rfcomm_info->address);
505         g_free(rfcomm_info->uuid);
506         g_free(rfcomm_info);
507         rfcomm_info = NULL;
508 }
509
510 int _bt_rfcomm_connect_using_uuid(int request_id,
511                         bluetooth_device_address_t *device_address,
512                         char *remote_uuid)
513 {
514         DBusGConnection *conn;
515         DBusGProxy *adapter_proxy;
516         DBusGProxy *device_proxy;
517         gchar *device_path = NULL;
518         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
519
520         BT_CHECK_PARAMETER(address, return);
521         BT_CHECK_PARAMETER(remote_uuid, return);
522         retv_if(rfcomm_info != NULL, BLUETOOTH_ERROR_DEVICE_BUSY);
523
524         adapter_proxy = _bt_get_adapter_proxy();
525         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
526
527         conn = _bt_get_system_gconn();
528         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
529
530         _bt_convert_addr_type_to_string(address, device_address->addr);
531
532         dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
533                           G_TYPE_STRING, address, G_TYPE_INVALID,
534                           DBUS_TYPE_G_OBJECT_PATH, &device_path, G_TYPE_INVALID);
535
536         retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
537
538         device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
539                                       device_path, BT_DEVICE_INTERFACE);
540         g_free(device_path);
541         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
542
543         rfcomm_info = g_malloc0(sizeof(rfcomm_function_data_t));
544         rfcomm_info->address = g_strdup(address);
545         rfcomm_info->uuid = g_strdup(remote_uuid);
546         rfcomm_info->req_id = request_id;
547
548         if (!dbus_g_proxy_begin_call(device_proxy, "DiscoverServices",
549                         (DBusGProxyCallNotify)__bt_rfcomm_discover_services_cb,
550                         NULL, NULL,
551                         G_TYPE_STRING, rfcomm_info->uuid,
552                         G_TYPE_INVALID)) {
553                 BT_ERR("Could not call dbus proxy\n");
554                 g_object_unref(device_proxy);
555                 g_free(rfcomm_info->address);
556                 g_free(rfcomm_info->uuid);
557                 g_free(rfcomm_info);
558                 rfcomm_info = NULL;
559                 return BLUETOOTH_ERROR_INTERNAL;
560         }
561
562         return BLUETOOTH_ERROR_NONE;
563 }
564
565 /* Range of the Channel : 0 <= channel <= 30 */
566 int _bt_rfcomm_connect_using_channel(int request_id,
567                         bluetooth_device_address_t *device_address,
568                         char *channel)
569 {
570         DBusGConnection *conn;
571         DBusGProxy *adapter_proxy;
572         DBusGProxy *device_proxy;
573         gchar *device_path = NULL;
574         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
575
576         BT_CHECK_PARAMETER(address, return);
577         retv_if(rfcomm_info != NULL, BLUETOOTH_ERROR_DEVICE_BUSY);
578
579         adapter_proxy = _bt_get_adapter_proxy();
580         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
581
582         conn = _bt_get_system_gconn();
583         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
584
585         _bt_convert_addr_type_to_string(address, device_address->addr);
586
587         dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
588                           G_TYPE_STRING, address, G_TYPE_INVALID,
589                           DBUS_TYPE_G_OBJECT_PATH, &device_path, G_TYPE_INVALID);
590
591         retv_if(device_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
592
593         device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
594                                                 device_path,
595                                                 BT_SERIAL_INTERFACE);
596         g_free(device_path);
597         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
598
599         rfcomm_info = g_malloc0(sizeof(rfcomm_function_data_t));
600         rfcomm_info->address = g_strdup(address);
601         rfcomm_info->channel = g_strdup(channel);
602         rfcomm_info->req_id = request_id;
603         rfcomm_info->rfcomm_proxy = device_proxy;
604
605         if (!dbus_g_proxy_begin_call(device_proxy, "Connect",
606                         (DBusGProxyCallNotify)__bt_rfcomm_connected_cb,
607                         NULL,   /*user_data*/
608                         NULL,   /*destroy*/
609                         G_TYPE_STRING, channel,
610                         G_TYPE_INVALID)) {
611                 BT_ERR("RFCOMM connect Dbus Call Error");
612                 g_object_unref(device_proxy);
613                 return BLUETOOTH_ERROR_INTERNAL;
614         }
615
616         BT_DBG("-\n");
617
618         return BLUETOOTH_ERROR_NONE;
619 }
620
621 /* Be used in RFCOMM client /server */
622 int _bt_rfcomm_disconnect(int socket_fd)
623 {
624         bt_rfcomm_info_t *socket_info;
625
626         socket_info = __bt_rfcomm_get_client_info(socket_fd);
627         if (socket_info == NULL)
628                 return _bt_rfcomm_server_disconnect(socket_fd);
629
630         return __bt_rfcomm_terminate_client(socket_fd);
631 }
632
633 /* Be used in RFCOMM client /server */
634 int _bt_rfcomm_write(int socket_fd, char *buf, int length)
635 {
636         int wbytes = 0;
637         int written;
638         int new_length;
639         char *ptr = NULL;
640
641         retv_if(buf == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
642
643         /* Check the utf8 validation & Fill the NULL in the invalid location*/
644         if (!g_utf8_validate(buf, -1, (const char **)&ptr))
645                 *ptr = '\0';
646
647         /* After calling g_utf8_validate, it is possible to be NULL */
648         retv_if(buf == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
649
650         new_length = strlen(buf);
651         if (new_length < length) {
652                 length = new_length;
653         }
654
655         /*some times user may send huge data */
656         while (wbytes < length) {
657                 written = write(socket_fd, buf + wbytes,
658                                 length - wbytes);
659                 if (written <= 0) {
660                         BT_ERR("write failed..\n");
661                         return BLUETOOTH_ERROR_NOT_IN_OPERATION;
662                 }
663
664                 /* Synchronize the sending buffer */
665                 sync();
666                 fsync(socket_fd);
667
668                 wbytes += written;
669         }
670
671         return BLUETOOTH_ERROR_NONE;
672 }
673
674 int _bt_rfcomm_cancel_connect(void)
675 {
676         GError *error = NULL;
677         char *input_param;
678
679         BT_DBG("+");
680
681         retv_if(rfcomm_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION);
682         retv_if(rfcomm_info->rfcomm_proxy == NULL,
683                                 BLUETOOTH_ERROR_INTERNAL);
684
685         if (rfcomm_info->uuid)
686                 input_param = rfcomm_info->uuid;
687         else
688                 input_param = rfcomm_info->channel;
689
690         retv_if(input_param == NULL, BLUETOOTH_ERROR_INTERNAL);
691
692         if (!dbus_g_proxy_call(rfcomm_info->rfcomm_proxy,
693                         "Disconnect",
694                         &error,
695                         G_TYPE_STRING, input_param,
696                         G_TYPE_INVALID, G_TYPE_INVALID)) {
697                 if (error) {
698                         BT_ERR("Disconnect Dbus Call Error, %s", error->message);
699                         g_error_free(error);
700                 }
701                 return BLUETOOTH_ERROR_INTERNAL;
702         }
703
704         /* Send the connected event after return the function */
705         g_idle_add((GSourceFunc) __bt_rfcomm_cancel_connect_cb, NULL);
706
707         BT_DBG("-");
708
709         return BLUETOOTH_ERROR_NONE;
710 }
711
712 int _bt_rfcomm_is_connected(gboolean *connected)
713 {
714         BT_CHECK_PARAMETER(connected, return);
715
716         *connected = (client_list == NULL || g_slist_length(client_list) == 0) ?
717                                         FALSE : TRUE;
718
719         return BLUETOOTH_ERROR_NONE;
720 }
721
722 int _bt_rfcomm_is_device_connected(bluetooth_device_address_t *device_address,
723                                         gboolean *connected)
724 {
725         GSList *l;
726         bt_rfcomm_info_t *client_info;
727         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
728
729         BT_CHECK_PARAMETER(device_address, return);
730         BT_CHECK_PARAMETER(connected, return);
731
732         _bt_convert_addr_type_to_string(address, device_address->addr);
733
734         *connected = FALSE;
735
736         for (l = client_list; l != NULL; l = l->next) {
737                 client_info = l->data;
738
739                 if (client_info == NULL)
740                         continue;
741
742                 if (g_strcmp0(address, client_info->address) == 0) {
743                         *connected = TRUE;
744                         return BLUETOOTH_ERROR_NONE;
745                 }
746         }
747
748         return BLUETOOTH_ERROR_NONE;
749 }
750
751 int _bt_rfcomm_client_disconnect_all(void)
752 {
753         GSList *l;
754         bt_rfcomm_info_t *client_info;
755
756         for (l = client_list; l != NULL; l = l->next) {
757                 client_info = l->data;
758
759                 if (client_info == NULL)
760                         continue;
761
762                 _bt_rfcomm_disconnect(client_info->fd);
763         }
764
765         return BLUETOOTH_ERROR_NONE;
766 }
767