Code Sync [Tizen3.0]: Merged the tizen_2.4 Spin code to tizen.org
[platform/core/connectivity/bluetooth-frwk.git] / bt-api / bt-rfcomm-server.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 <string.h>
25 #ifdef RFCOMM_DIRECT
26 #include <gio/gio.h>
27 #include <gio/gunixfdlist.h>
28 #include <sys/socket.h>
29 #endif
30
31 #include "bluetooth-api.h"
32 #include "bt-internal-types.h"
33
34 #include "bt-common.h"
35 #include "bt-request-sender.h"
36 #include "bt-event-handler.h"
37
38 #ifdef RFCOMM_DIRECT
39
40 static GSList *rfcomm_nodes;
41
42 typedef struct {
43         guint object_id;
44         gchar *path;
45         int id;
46         char *uuid;
47         int fd;
48         GIOChannel *data_io;
49         guint data_id;
50         bluetooth_device_address_t addr;
51         guint disconnect_idle_id;
52 } rfcomm_info_t;
53
54 static rfcomm_info_t *__find_rfcomm_info_with_id(int id)
55 {
56         GSList *l;
57
58         for (l = rfcomm_nodes; l != NULL; l = l->next) {
59                 rfcomm_info_t *info = l->data;
60
61                 if (info->id == id)
62                         return info;
63         }
64
65         return NULL;
66 }
67
68 static rfcomm_info_t *__find_rfcomm_info_with_fd(int fd)
69 {
70         GSList *l;
71
72         for (l = rfcomm_nodes; l != NULL; l = l->next) {
73                 rfcomm_info_t *info = l->data;
74
75                 if (info->fd == fd)
76                         return info;
77         }
78
79         return NULL;
80 }
81
82 static rfcomm_info_t *__find_rfcomm_info_with_path(const gchar *path)
83 {
84         GSList *l;
85
86         for (l = rfcomm_nodes; l != NULL; l = l->next) {
87                 rfcomm_info_t *info = l->data;
88
89                 if (g_strcmp0(info->path, path) == 0)
90                         return info;
91         }
92
93         return NULL;
94 }
95
96 gboolean _check_uuid_path(char *path, char *uuid)
97 {
98         rfcomm_info_t *info = NULL;
99         info = __find_rfcomm_info_with_path(path);
100         if (!info)
101                 return FALSE;
102
103         if (strcmp(info->uuid, uuid) == 0)
104                 return TRUE;
105
106         return FALSE;
107 }
108
109 static void __connected_cb(rfcomm_info_t *info, bt_event_info_t *event_info)
110 {
111         bluetooth_rfcomm_connection_t conn_info;
112
113         memset(&conn_info, 0x00, sizeof(bluetooth_rfcomm_connection_t));
114         conn_info.device_role = RFCOMM_ROLE_SERVER;
115         g_strlcpy(conn_info.uuid, info->uuid, BLUETOOTH_UUID_STRING_MAX);
116         conn_info.socket_fd = info->fd;
117         conn_info.device_addr = info->addr;
118         conn_info.server_id = info->id;
119
120         BT_INFO_C("Connected [RFCOMM Server]");
121         _bt_common_event_cb(BLUETOOTH_EVENT_RFCOMM_CONNECTED,
122                         BLUETOOTH_ERROR_NONE, &conn_info,
123                         event_info->cb, event_info->user_data);
124 }
125
126 static gboolean __rfcomm_server_disconnect(rfcomm_info_t *info)
127 {
128         bluetooth_rfcomm_disconnection_t disconn_info;
129         int fd = info->fd;
130         bt_event_info_t *event_info;
131
132         BT_INFO_C("Disconnected [RFCOMM Server]");
133
134         if (info->data_id > 0) {
135                 g_source_remove(info->data_id);
136                 info->data_id = 0;
137         }
138
139         if (info->fd >= 0) {
140                 close(info->fd);
141                 info->fd = -1;
142         }
143
144         if (info->data_io) {
145                 g_io_channel_shutdown(info->data_io, TRUE, NULL);
146                 g_io_channel_unref(info->data_io);
147                 info->data_io = NULL;
148         }
149         info->disconnect_idle_id = 0;
150         event_info = _bt_event_get_cb_data(BT_RFCOMM_SERVER_EVENT);
151         if (event_info == NULL)
152                 return FALSE;
153
154         memset(&disconn_info, 0x00, sizeof(bluetooth_rfcomm_disconnection_t));
155         disconn_info.device_role = RFCOMM_ROLE_SERVER;
156         g_strlcpy(disconn_info.uuid, info->uuid, BLUETOOTH_UUID_STRING_MAX);
157         disconn_info.socket_fd = fd;
158         disconn_info.device_addr = info->addr;
159
160         _bt_common_event_cb(BLUETOOTH_EVENT_RFCOMM_DISCONNECTED,
161                         BLUETOOTH_ERROR_NONE, &disconn_info,
162                         event_info->cb, event_info->user_data);
163
164         BT_DBG("-");
165         return FALSE;
166 }
167
168 static gboolean __data_received_cb(GIOChannel *chan, GIOCondition cond,
169                                                                 gpointer data)
170 {
171         char *buffer = NULL;
172         gsize len = 0;
173         int result = BLUETOOTH_ERROR_NONE;
174         rfcomm_info_t *info = data;
175         bt_event_info_t *event_info;
176         bluetooth_rfcomm_received_data_t data_r;
177         GIOStatus status = G_IO_STATUS_NORMAL;
178         GError *err = NULL;
179
180         retv_if(info == NULL, FALSE);
181
182         event_info = _bt_event_get_cb_data(BT_RFCOMM_SERVER_EVENT);
183
184         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
185                 BT_ERR_C("RFComm Server  disconnected: %d", info->fd);
186
187                 if (info->disconnect_idle_id > 0) {
188                         BT_INFO("Disconnect idle still not process remove source");
189                         g_source_remove(info->disconnect_idle_id);
190                         info->disconnect_idle_id = 0;
191                 }
192
193                 __rfcomm_server_disconnect(info);
194                 return FALSE;
195         }
196
197         buffer = g_malloc0(BT_RFCOMM_BUFFER_LEN + 1);
198
199         status =  g_io_channel_read_chars(chan, buffer, BT_RFCOMM_BUFFER_LEN,
200                         &len, &err);
201         if (status != G_IO_STATUS_NORMAL) {
202                 BT_ERR("IO Channel read is failed with %d", status);
203
204                 g_free(buffer);
205                 if (err) {
206                         BT_ERR("IO Channel read error [%s]", err->message);
207                         if (status == G_IO_STATUS_ERROR &&
208                             !g_strcmp0(err->message, "Connection reset by peer")) {
209                                 BT_ERR("cond : %d", cond);
210                                 g_error_free(err);
211                                 if (info->disconnect_idle_id > 0) {
212                                         BT_INFO("Disconnect idle still not process remove source");
213                                         g_source_remove(info->disconnect_idle_id);
214                                         info->disconnect_idle_id = 0;
215                                 }
216                                 __rfcomm_server_disconnect(info);
217                                 return FALSE;
218                         }
219                         g_error_free(err);
220                 }
221                 return TRUE;
222         }
223
224         if (len == 0)
225                 BT_ERR("Length is zero");
226
227         if (event_info == NULL) {
228                 g_free(buffer);
229                 return TRUE;
230         }
231
232         data_r.socket_fd = info->fd;
233         data_r.buffer_size = len;
234         data_r.buffer = buffer;
235
236         _bt_common_event_cb(BLUETOOTH_EVENT_RFCOMM_DATA_RECEIVED,
237                         result, &data_r,
238                         event_info->cb, event_info->user_data);
239
240         g_free(buffer);
241
242         return TRUE;
243 }
244
245 int new_server_connection(const char *path, int fd, bluetooth_device_address_t *addr)
246 {
247         rfcomm_info_t *info;
248         bt_event_info_t *event_info;
249
250         BT_DBG("%s %d", path, fd);
251
252         info = __find_rfcomm_info_with_path(path);
253         if (info == NULL)
254                 return -1;
255
256         info->fd = fd;
257         memcpy(&info->addr, addr, sizeof(bluetooth_device_address_t));
258
259         info->data_io = g_io_channel_unix_new(info->fd);
260
261         g_io_channel_set_encoding(info->data_io, NULL, NULL);
262         g_io_channel_set_flags(info->data_io, G_IO_FLAG_NONBLOCK, NULL);
263
264         info->data_id = g_io_add_watch(info->data_io,
265                            G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
266                            __data_received_cb, info);
267
268         event_info = _bt_event_get_cb_data(BT_RFCOMM_SERVER_EVENT);
269         if (event_info) {
270                 __connected_cb(info, event_info);
271         }
272
273         return 0;
274 }
275
276 static rfcomm_info_t *__register_method()
277 {
278         gchar *path;
279         rfcomm_info_t *info;
280         int object_id;
281         int id;
282
283         id = __rfcomm_assign_id();
284         if (id < 0)
285                 return NULL;
286
287         path = g_strdup_printf("/org/socket/server/%d/%d", getpid(), id);
288
289         object_id = _bt_register_new_conn(path, new_server_connection);
290         if (object_id < 0) {
291                 __rfcomm_delete_id(id);
292                 return NULL;
293         }
294         info = g_new(rfcomm_info_t, 1);
295         info->object_id = (guint)object_id;
296         info->path = path;
297         info->id = id;
298         info->fd = -1;
299
300         rfcomm_nodes = g_slist_append(rfcomm_nodes, info);
301
302         return info;
303 }
304
305 void free_rfcomm_info(rfcomm_info_t *info)
306 {
307         bt_event_info_t *event_info;
308
309         BT_DBG("");
310         if (info->disconnect_idle_id > 0) {
311                 BT_INFO("Disconnect idle still not process remove source");
312                 g_source_remove(info->disconnect_idle_id);
313                 info->disconnect_idle_id = 0;
314         }
315
316         __rfcomm_delete_id(info->id);
317         _bt_unregister_gdbus(info->object_id);
318
319         if (info->fd >= 0) {
320                 event_info = _bt_event_get_cb_data(BT_RFCOMM_SERVER_EVENT);
321                 if (event_info)
322                         BT_DBG("event type %d", event_info->event_type);
323                 __rfcomm_server_disconnect(info);
324         }
325
326         g_free(info->path);
327         g_free(info->uuid);
328         g_free(info);
329 }
330
331 void _bt_rfcomm_server_free_all()
332 {
333         BT_DBG("Free all the servers");
334
335         g_slist_free_full(rfcomm_nodes, (GDestroyNotify)free_rfcomm_info);
336         rfcomm_nodes = NULL;
337 }
338 #endif
339
340 BT_EXPORT_API int bluetooth_rfcomm_create_socket(const char *uuid)
341 {
342 #ifdef RFCOMM_DIRECT
343         rfcomm_info_t *info;
344 #else
345         int result;
346         int socket_fd = -1;
347         char uuid_str[BLUETOOTH_UUID_STRING_MAX];
348 #endif
349
350         BT_CHECK_ENABLED(return);
351         BT_CHECK_PARAMETER(uuid, return);
352         BT_INFO("UUID Provided %s", uuid);
353
354         if (_bt_check_privilege(BT_BLUEZ_SERVICE, BT_RFCOMM_CREATE_SOCKET)
355                 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
356                 BT_ERR("Don't have a privilege to use this API");
357                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
358         }
359
360 #ifdef RFCOMM_DIRECT
361         BT_INFO("<<<<<<<<< RFCOMM Create socket from app >>>>>>>>>");
362         info = __register_method();
363         if (info == NULL)
364                 return -1;
365
366         info->uuid = g_strdup(uuid);
367         info->disconnect_idle_id = 0;
368         return info->id;
369 #else
370
371         BT_INIT_PARAMS();
372         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
373
374         g_strlcpy(uuid_str, uuid, sizeof(uuid_str));
375         g_array_append_vals(in_param1, uuid_str, BLUETOOTH_UUID_STRING_MAX);
376
377         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_CREATE_SOCKET,
378                 in_param1, in_param2, in_param3, in_param4, &out_param);
379
380         BT_DBG("result: %x", result);
381
382         if (result == BLUETOOTH_ERROR_NONE) {
383                 socket_fd = g_array_index(out_param, int, 0);
384         } else {
385                 BT_ERR("Fail to send request");
386         }
387
388         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
389
390         return socket_fd;
391 #endif
392 }
393
394 BT_EXPORT_API int bluetooth_rfcomm_remove_socket(int socket_fd)
395 {
396 #ifdef RFCOMM_DIRECT
397         rfcomm_info_t *info;
398 #else
399         int result;
400 #endif
401
402         BT_CHECK_ENABLED(return);
403
404         if (_bt_check_privilege(BT_BLUEZ_SERVICE, BT_RFCOMM_REMOVE_SOCKET)
405                 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
406                 BT_ERR("Don't have a privilege to use this API");
407                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
408         }
409
410 #ifdef RFCOMM_DIRECT
411         BT_INFO("<<<<<<<<< RFCOMM Remove socket request from app, fd=[%d] >>>>>>>>>>>", socket_fd);
412
413         info = __find_rfcomm_info_with_id(socket_fd);
414         if (info == NULL)
415                 return BLUETOOTH_ERROR_INVALID_PARAM;
416
417         _bt_unregister_osp_server_in_agent(BT_RFCOMM_SERVER,info->uuid);
418         _bt_unregister_profile(info->path);
419
420         rfcomm_nodes = g_slist_remove(rfcomm_nodes, info);
421         free_rfcomm_info(info);
422
423         return BLUETOOTH_ERROR_NONE;
424 #else
425         BT_INIT_PARAMS();
426         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
427
428         g_array_append_vals(in_param1, &socket_fd, sizeof(int));
429
430         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_REMOVE_SOCKET,
431                 in_param1, in_param2, in_param3, in_param4, &out_param);
432
433         BT_DBG("result: %x", result);
434
435         if (result == BLUETOOTH_ERROR_NONE) {
436                 _bt_remove_server(socket_fd);
437         }
438
439         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
440
441         return result;
442 #endif
443 }
444
445 BT_EXPORT_API int bluetooth_rfcomm_server_disconnect(int socket_fd)
446 {
447 #ifdef RFCOMM_DIRECT
448         rfcomm_info_t *info;
449
450         char address[20];
451
452         BT_INFO(">>>>>>>>RFCOMM server disconnect request from APP>>>>>>>>>");
453
454         info = __find_rfcomm_info_with_fd(socket_fd);
455         if (info == NULL)
456                 return BLUETOOTH_ERROR_INVALID_PARAM;
457
458         if (info->data_io == NULL)
459                 return BLUETOOTH_ERROR_NOT_CONNECTED;
460
461         g_io_channel_shutdown(info->data_io, TRUE, NULL);
462         g_io_channel_unref(info->data_io);
463         info->data_io = NULL;
464
465         _bt_convert_addr_type_to_string(address, info->addr.addr);
466         BT_DBG("Address %s", address);
467         _bt_disconnect_profile(address, info->uuid, NULL,NULL);
468
469         info->disconnect_idle_id = g_idle_add(__rfcomm_server_disconnect, info);
470         BT_DBG("-");
471
472         return BLUETOOTH_ERROR_NONE;
473 #else
474         int result;
475
476         BT_CHECK_ENABLED(return);
477
478         BT_INIT_PARAMS();
479         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
480
481         g_array_append_vals(in_param1, &socket_fd, sizeof(int));
482
483         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_SOCKET_DISCONNECT,
484                 in_param1, in_param2, in_param3, in_param4, &out_param);
485
486         BT_DBG("result: %x", result);
487
488         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
489
490         return result;
491 #endif
492 }
493
494 BT_EXPORT_API gboolean bluetooth_rfcomm_is_server_uuid_available(const char *uuid)
495 {
496         int result;
497         gboolean available = TRUE;
498         char uuid_str[BLUETOOTH_UUID_STRING_MAX];
499
500         retv_if(uuid == NULL, FALSE);
501         retv_if(bluetooth_check_adapter() ==
502                                 BLUETOOTH_ADAPTER_DISABLED, FALSE);
503
504         BT_INIT_PARAMS();
505         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
506
507         g_strlcpy(uuid_str, uuid, sizeof(uuid_str));
508         g_array_append_vals(in_param1, uuid_str, BLUETOOTH_UUID_STRING_MAX);
509
510         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_IS_UUID_AVAILABLE,
511                 in_param1, in_param2, in_param3, in_param4, &out_param);
512
513         BT_DBG("result: %x", result);
514
515         if (result == BLUETOOTH_ERROR_NONE) {
516                 available = g_array_index(out_param, gboolean, 0);
517         }
518
519         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
520
521         BT_DBG("available: %d", available);
522
523         return available;
524 }
525
526 BT_EXPORT_API int bluetooth_rfcomm_server_is_connected(bluetooth_device_address_t *device_address, gboolean *connected)
527 {
528         GSList *l;
529         rfcomm_info_t *info;
530         char connected_addr[BT_ADDRESS_STRING_SIZE] = { 0 };
531         char input_addr[BT_ADDRESS_STRING_SIZE] = { 0 };
532
533         BT_CHECK_PARAMETER(device_address, return);
534         BT_CHECK_PARAMETER(connected, return);
535
536         _bt_convert_addr_type_to_string(input_addr, device_address->addr);
537
538         *connected = FALSE;
539
540         for (l = rfcomm_nodes; l != NULL; l = l->next) {
541                 info = l->data;
542
543                 if (info == NULL)
544                         continue;
545                 _bt_convert_addr_type_to_string(connected_addr, info->addr.addr);
546
547                 if (g_strcmp0(connected_addr, input_addr) == 0) {
548                         *connected = TRUE;
549                         return BLUETOOTH_ERROR_NONE;
550                 }
551         }
552
553         return BLUETOOTH_ERROR_NONE;
554 }
555
556 BT_EXPORT_API int bluetooth_rfcomm_listen_and_accept(int socket_fd, int max_pending_connection)
557 {
558 #ifdef RFCOMM_DIRECT
559         rfcomm_info_t *info;
560 #else
561         int result;
562         gboolean native_service = TRUE;
563 #endif
564
565         BT_CHECK_ENABLED(return);
566
567 #ifdef RFCOMM_DIRECT
568         BT_INFO("<<<<<<<<< RFCOMM Listen & accept from app >>>>>>>>>>>");
569
570         info = __find_rfcomm_info_with_id(socket_fd);
571         if (info == NULL)
572                 return BLUETOOTH_ERROR_INVALID_PARAM;
573
574         bt_register_profile_info_t profile_info;
575         int result;
576
577         profile_info.authentication = TRUE;
578         profile_info.authorization = TRUE;
579         profile_info.obj_path = info->path;
580         profile_info.role = NULL;
581         profile_info.service = info->uuid;
582         profile_info.uuid = info->uuid;
583         BT_INFO("uuid %s", profile_info.uuid);
584         result = _bt_register_profile(&profile_info, TRUE);
585
586         return result;
587 #else
588         BT_INIT_PARAMS();
589         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
590
591         g_array_append_vals(in_param1, &socket_fd, sizeof(int));
592         g_array_append_vals(in_param2, &max_pending_connection, sizeof(int));
593         g_array_append_vals(in_param3, &native_service, sizeof(gboolean));
594
595         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_LISTEN,
596                 in_param1, in_param2, in_param3, in_param4, &out_param);
597
598         BT_DBG("result: %x", result);
599
600         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
601
602         return result;
603 #endif
604 }
605
606 BT_EXPORT_API int bluetooth_rfcomm_listen(int socket_fd, int max_pending_connection)
607 {
608 #ifdef RFCOMM_DIRECT
609         rfcomm_info_t *info;
610 #else
611         int result;
612         gboolean native_service = FALSE;
613 #endif
614
615         BT_CHECK_ENABLED(return);
616
617 #ifdef RFCOMM_DIRECT
618         BT_INFO("<<<<<<<<< RFCOMM Listen >>>>>>>>>>>");
619
620         info = __find_rfcomm_info_with_id(socket_fd);
621         if (info == NULL)
622                 return BLUETOOTH_ERROR_INVALID_PARAM;
623
624         bt_register_profile_info_t profile_info;
625         int result;
626
627         profile_info.authentication = TRUE;
628         profile_info.authorization = TRUE;
629         profile_info.obj_path = info->path;
630         profile_info.role = NULL;
631         profile_info.service = info->uuid;
632         profile_info.uuid = info->uuid;
633         BT_INFO("UUID %s", info->uuid);
634         BT_INFO("PATH %s", info->path);
635         result = _bt_register_profile_platform(&profile_info, TRUE);
636         if (result != BLUETOOTH_ERROR_NONE)
637                 return result;
638
639         return _bt_register_osp_server_in_agent(BT_RFCOMM_SERVER, info->uuid,
640                                                 info->path, socket_fd);
641
642 #else
643         BT_INIT_PARAMS();
644         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
645
646         g_array_append_vals(in_param1, &socket_fd, sizeof(int));
647         g_array_append_vals(in_param2, &max_pending_connection, sizeof(int));
648         g_array_append_vals(in_param3, &native_service, sizeof(gboolean));
649
650         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_LISTEN,
651                 in_param1, in_param2, in_param3, in_param4, &out_param);
652
653         BT_DBG("result: %x", result);
654
655         if (result == BLUETOOTH_ERROR_NONE) {
656                 _bt_add_server(socket_fd);
657         }
658
659         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
660
661         return result;
662 #endif
663 }
664
665 BT_EXPORT_API int bluetooth_rfcomm_accept_connection(int server_fd)
666 {
667         int result;
668
669         BT_CHECK_ENABLED(return);
670
671         BT_INIT_PARAMS();
672         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
673
674         g_array_append_vals(in_param1, &server_fd, sizeof(int));
675
676         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_ACCEPT_CONNECTION,
677                 in_param1, in_param2, in_param3, in_param4, &out_param);
678
679         BT_DBG("result: %x", result);
680
681         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
682
683         return result;
684 }
685
686 BT_EXPORT_API int bluetooth_rfcomm_reject_connection(int server_fd)
687 {
688         int result;
689
690         BT_CHECK_ENABLED(return);
691
692         BT_INFO("+");
693
694         BT_INIT_PARAMS();
695         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
696
697         g_array_append_vals(in_param1, &server_fd, sizeof(int));
698
699         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_REJECT_CONNECTION,
700                 in_param1, in_param2, in_param3, in_param4, &out_param);
701
702         BT_DBG("result: %x", result);
703
704         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
705
706         return result;
707 }
708