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