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