Merge "DPM: Add basic code for device policy manager for BT." into tizen
[platform/core/connectivity/bluetooth-frwk.git] / bt-api / bt-rfcomm-server.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *              http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <string.h>
19 #ifdef RFCOMM_DIRECT
20 #include <gio/gio.h>
21 #include <gio/gunixfdlist.h>
22 #include <sys/socket.h>
23 #endif
24
25 #include "bluetooth-api.h"
26 #include "bt-internal-types.h"
27
28 #include "bt-common.h"
29 #include "bt-request-sender.h"
30 #include "bt-event-handler.h"
31
32 #ifdef RFCOMM_DIRECT
33
34 static GSList *rfcomm_nodes;
35
36 typedef struct {
37         guint object_id;
38         gchar *path;
39         int id;
40         char *uuid;
41         int fd;
42         GIOChannel *data_io;
43         guint data_id;
44         bluetooth_device_address_t addr;
45         guint disconnect_idle_id;
46 } rfcomm_info_t;
47
48 static rfcomm_info_t *__find_rfcomm_info_with_id(int id)
49 {
50         GSList *l;
51
52         for (l = rfcomm_nodes; l != NULL; l = l->next) {
53                 rfcomm_info_t *info = l->data;
54
55                 if (info->id == id)
56                         return info;
57         }
58
59         return NULL;
60 }
61
62 static rfcomm_info_t *__find_rfcomm_info_with_fd(int fd)
63 {
64         GSList *l;
65
66         for (l = rfcomm_nodes; l != NULL; l = l->next) {
67                 rfcomm_info_t *info = l->data;
68
69                 if (info->fd == fd)
70                         return info;
71         }
72
73         return NULL;
74 }
75
76 static rfcomm_info_t *__find_rfcomm_info_with_path(const gchar *path)
77 {
78         GSList *l;
79
80         for (l = rfcomm_nodes; l != NULL; l = l->next) {
81                 rfcomm_info_t *info = l->data;
82
83                 if (g_strcmp0(info->path, path) == 0)
84                         return info;
85         }
86
87         return NULL;
88 }
89
90 static rfcomm_info_t *__find_rfcomm_info_with_uuid(const char *uuid)
91 {
92         GSList *l;
93
94         for (l = rfcomm_nodes; l != NULL; l = l->next) {
95                 rfcomm_info_t *info = l->data;
96
97                 if (g_strcmp0(info->uuid, uuid) == 0)
98                         return info;
99         }
100
101         return NULL;
102 }
103
104 gboolean _check_uuid_path(char *path, char *uuid)
105 {
106         rfcomm_info_t *info = NULL;
107         info = __find_rfcomm_info_with_path(path);
108         if (!info)
109                 return FALSE;
110
111         if (strcmp(info->uuid, uuid) == 0)
112                 return TRUE;
113
114         return FALSE;
115 }
116
117 static void __connected_cb(rfcomm_info_t *info, bt_event_info_t *event_info)
118 {
119         bluetooth_rfcomm_connection_t conn_info;
120
121         memset(&conn_info, 0x00, sizeof(bluetooth_rfcomm_connection_t));
122         conn_info.device_role = RFCOMM_ROLE_SERVER;
123         g_strlcpy(conn_info.uuid, info->uuid, BLUETOOTH_UUID_STRING_MAX);
124         conn_info.socket_fd = info->fd;
125         conn_info.device_addr = info->addr;
126         conn_info.server_id = info->id;
127
128         BT_INFO_C("Connected [RFCOMM Server]");
129         _bt_common_event_cb(BLUETOOTH_EVENT_RFCOMM_CONNECTED,
130                         BLUETOOTH_ERROR_NONE, &conn_info,
131                         event_info->cb, event_info->user_data);
132 }
133
134 static gboolean __rfcomm_server_disconnect(rfcomm_info_t *info)
135 {
136         bluetooth_rfcomm_disconnection_t disconn_info;
137         int fd = info->fd;
138         bt_event_info_t *event_info;
139
140         BT_INFO_C("Disconnected [RFCOMM Server]");
141
142         if (info->data_id > 0) {
143                 g_source_remove(info->data_id);
144                 info->data_id = 0;
145         }
146
147         if (info->fd >= 0) {
148                 close(info->fd);
149                 info->fd = -1;
150         }
151
152         if (info->data_io) {
153                 g_io_channel_shutdown(info->data_io, TRUE, NULL);
154                 g_io_channel_unref(info->data_io);
155                 info->data_io = NULL;
156         }
157         info->disconnect_idle_id = 0;
158         event_info = _bt_event_get_cb_data(BT_RFCOMM_SERVER_EVENT);
159         if (event_info == NULL)
160                 return FALSE;
161
162         memset(&disconn_info, 0x00, sizeof(bluetooth_rfcomm_disconnection_t));
163         disconn_info.device_role = RFCOMM_ROLE_SERVER;
164         g_strlcpy(disconn_info.uuid, info->uuid, BLUETOOTH_UUID_STRING_MAX);
165         disconn_info.socket_fd = fd;
166         disconn_info.device_addr = info->addr;
167
168         _bt_common_event_cb(BLUETOOTH_EVENT_RFCOMM_DISCONNECTED,
169                         BLUETOOTH_ERROR_NONE, &disconn_info,
170                         event_info->cb, event_info->user_data);
171
172         BT_DBG("-");
173         return FALSE;
174 }
175
176 static gboolean __data_received_cb(GIOChannel *chan, GIOCondition cond,
177                                                                 gpointer data)
178 {
179         char *buffer = NULL;
180         gsize len = 0;
181         int result = BLUETOOTH_ERROR_NONE;
182         rfcomm_info_t *info = data;
183         bt_event_info_t *event_info;
184         bluetooth_rfcomm_received_data_t data_r;
185         GIOStatus status = G_IO_STATUS_NORMAL;
186         GError *err = NULL;
187
188         retv_if(info == NULL, FALSE);
189
190         event_info = _bt_event_get_cb_data(BT_RFCOMM_SERVER_EVENT);
191
192         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
193                 BT_ERR_C("RFComm Server  disconnected: %d", info->fd);
194
195                 if (info->disconnect_idle_id > 0) {
196                         BT_INFO("Disconnect idle still not process remove source");
197                         g_source_remove(info->disconnect_idle_id);
198                         info->disconnect_idle_id = 0;
199                 }
200
201                 __rfcomm_server_disconnect(info);
202                 return FALSE;
203         }
204
205         buffer = g_malloc0(BT_RFCOMM_BUFFER_LEN + 1);
206
207         status =  g_io_channel_read_chars(chan, buffer, BT_RFCOMM_BUFFER_LEN,
208                         &len, &err);
209         if (status != G_IO_STATUS_NORMAL) {
210                 BT_ERR("IO Channel read is failed with %d", status);
211
212                 g_free(buffer);
213                 if (err) {
214                         BT_ERR("IO Channel read error [%s]", err->message);
215                         if (status == G_IO_STATUS_ERROR &&
216                             !g_strcmp0(err->message, "Connection reset by peer")) {
217                                 BT_ERR("cond : %d", cond);
218                                 g_error_free(err);
219                                 if (info->disconnect_idle_id > 0) {
220                                         BT_INFO("Disconnect idle still not process remove source");
221                                         g_source_remove(info->disconnect_idle_id);
222                                         info->disconnect_idle_id = 0;
223                                 }
224                                 __rfcomm_server_disconnect(info);
225                                 return FALSE;
226                         }
227                         g_error_free(err);
228                 }
229                 return TRUE;
230         }
231
232         if (len == 0)
233                 BT_ERR("Length is zero");
234
235         if (event_info == NULL) {
236                 g_free(buffer);
237                 return TRUE;
238         }
239
240         data_r.socket_fd = info->fd;
241         data_r.buffer_size = len;
242         data_r.buffer = buffer;
243
244         _bt_common_event_cb(BLUETOOTH_EVENT_RFCOMM_DATA_RECEIVED,
245                         result, &data_r,
246                         event_info->cb, event_info->user_data);
247
248         g_free(buffer);
249
250         return TRUE;
251 }
252
253 int new_server_connection(const char *path, int fd, bluetooth_device_address_t *addr)
254 {
255         rfcomm_info_t *info;
256         bt_event_info_t *event_info;
257
258         BT_DBG("%s %d", path, fd);
259
260         info = __find_rfcomm_info_with_path(path);
261         if (info == NULL)
262                 return -1;
263
264         info->fd = fd;
265         memcpy(&info->addr, addr, sizeof(bluetooth_device_address_t));
266
267         info->data_io = g_io_channel_unix_new(info->fd);
268
269         g_io_channel_set_encoding(info->data_io, NULL, NULL);
270         g_io_channel_set_flags(info->data_io, G_IO_FLAG_NONBLOCK, NULL);
271
272         info->data_id = g_io_add_watch(info->data_io,
273                            G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
274                            __data_received_cb, info);
275
276         event_info = _bt_event_get_cb_data(BT_RFCOMM_SERVER_EVENT);
277         if (event_info) {
278                 __connected_cb(info, event_info);
279         }
280
281         return 0;
282 }
283
284 static rfcomm_info_t *__register_method()
285 {
286         gchar *path;
287         rfcomm_info_t *info;
288         int object_id;
289         int id;
290
291         id = __rfcomm_assign_id();
292         if (id < 0)
293                 return NULL;
294
295         path = g_strdup_printf("/org/socket/server/%d/%d", getpid(), id);
296
297         object_id = _bt_register_new_conn(path, new_server_connection);
298         if (object_id < 0) {
299                 __rfcomm_delete_id(id);
300                 return NULL;
301         }
302         info = g_new(rfcomm_info_t, 1);
303         info->object_id = (guint)object_id;
304         info->path = path;
305         info->id = id;
306         info->fd = -1;
307
308         rfcomm_nodes = g_slist_append(rfcomm_nodes, info);
309
310         return info;
311 }
312
313 static rfcomm_info_t *__register_method_2(const char *path,const char *bus_name)
314 {
315         rfcomm_info_t *info;
316         int object_id;
317
318         object_id = _bt_register_new_conn_ex(path, bus_name, new_server_connection);
319         if (object_id < 0) {
320                 return NULL;
321         }
322         info = g_new(rfcomm_info_t, 1);
323         info->object_id = (guint)object_id;
324         info->path = g_strdup(path);
325         info->id = -1;
326         info->fd = -1;
327
328         rfcomm_nodes = g_slist_append(rfcomm_nodes, info);
329
330         return info;
331 }
332
333 void free_rfcomm_info(rfcomm_info_t *info)
334 {
335         bt_event_info_t *event_info;
336
337         BT_DBG("");
338         if (info->disconnect_idle_id > 0) {
339                 BT_INFO("Disconnect idle still not process remove source");
340                 g_source_remove(info->disconnect_idle_id);
341                 info->disconnect_idle_id = 0;
342         }
343
344         __rfcomm_delete_id(info->id);
345         _bt_unregister_gdbus(info->object_id);
346
347         if (info->fd >= 0) {
348                 event_info = _bt_event_get_cb_data(BT_RFCOMM_SERVER_EVENT);
349                 if (event_info)
350                         BT_DBG("event type %d", event_info->event_type);
351                 __rfcomm_server_disconnect(info);
352         }
353
354         g_free(info->path);
355         g_free(info->uuid);
356         g_free(info);
357 }
358
359 void _bt_rfcomm_server_free_all()
360 {
361         BT_DBG("Free all the servers");
362
363         g_slist_free_full(rfcomm_nodes, (GDestroyNotify)free_rfcomm_info);
364         rfcomm_nodes = NULL;
365 }
366 #endif
367
368 BT_EXPORT_API int bluetooth_rfcomm_create_socket(const char *uuid)
369 {
370 #ifdef RFCOMM_DIRECT
371         rfcomm_info_t *info;
372 #else
373         int result;
374         int socket_fd = -1;
375         char uuid_str[BLUETOOTH_UUID_STRING_MAX];
376 #endif
377
378         BT_CHECK_ENABLED(return);
379         BT_CHECK_PARAMETER(uuid, return);
380         BT_INFO("UUID Provided %s", uuid);
381
382         if (_bt_check_privilege(BT_BLUEZ_SERVICE, BT_RFCOMM_CREATE_SOCKET)
383                 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
384                 BT_ERR("Don't have a privilege to use this API");
385                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
386         }
387
388 #ifdef RFCOMM_DIRECT
389         BT_INFO("<<<<<<<<< RFCOMM Create socket from app >>>>>>>>>");
390         info = __register_method();
391         if (info == NULL)
392                 return -1;
393
394         info->uuid = g_strdup(uuid);
395         info->disconnect_idle_id = 0;
396         return info->id;
397 #else
398
399         BT_INIT_PARAMS();
400         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
401
402         g_strlcpy(uuid_str, uuid, sizeof(uuid_str));
403         g_array_append_vals(in_param1, uuid_str, BLUETOOTH_UUID_STRING_MAX);
404
405         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_CREATE_SOCKET,
406                 in_param1, in_param2, in_param3, in_param4, &out_param);
407
408         BT_DBG("result: %x", result);
409
410         if (result == BLUETOOTH_ERROR_NONE) {
411                 socket_fd = g_array_index(out_param, int, 0);
412         } else {
413                 BT_ERR("Fail to send request");
414         }
415
416         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
417
418         return socket_fd;
419 #endif
420 }
421
422 BT_EXPORT_API int bluetooth_rfcomm_create_socket_ex(const char *uuid, const char *bus_name, const char *path)
423 {
424 #ifdef RFCOMM_DIRECT
425         rfcomm_info_t *info;
426
427         BT_CHECK_ENABLED(return);
428         BT_CHECK_PARAMETER(path, return);
429         BT_INFO("PATH Provided %s", path);
430
431         if (_bt_check_privilege(BT_BLUEZ_SERVICE, BT_RFCOMM_CREATE_SOCKET_EX)
432                 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
433                 BT_ERR("Don't have a privilege to use this API");
434                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
435         }
436
437         BT_INFO("<<<<<<<<< RFCOMM Create socket from app >>>>>>>>>");
438         info = __register_method_2(path, bus_name);
439         if (info == NULL)
440                 return BLUETOOTH_ERROR_IN_PROGRESS;
441         info->uuid = g_strdup(uuid);
442         info->disconnect_idle_id = 0;
443
444         return BLUETOOTH_ERROR_NONE;
445 #else
446         return BLUETOOTH_ERROR_NOT_SUPPORT;
447 #endif
448 }
449
450
451 BT_EXPORT_API int bluetooth_rfcomm_remove_socket(int socket_fd)
452 {
453 #ifdef RFCOMM_DIRECT
454         rfcomm_info_t *info;
455 #else
456         int result;
457 #endif
458
459         BT_CHECK_ENABLED(return);
460
461         if (_bt_check_privilege(BT_BLUEZ_SERVICE, BT_RFCOMM_REMOVE_SOCKET)
462                 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
463                 BT_ERR("Don't have a privilege to use this API");
464                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
465         }
466
467         if (socket_fd < 0) {
468                 BT_ERR("Invalid FD");
469                 return BLUETOOTH_ERROR_INVALID_PARAM;
470         }
471
472 #ifdef RFCOMM_DIRECT
473         BT_INFO("<<<<<<<<< RFCOMM Remove socket request from app, fd=[%d] >>>>>>>>>>>", socket_fd);
474
475         info = __find_rfcomm_info_with_id(socket_fd);
476         if (info == NULL)
477                 return BLUETOOTH_ERROR_INVALID_PARAM;
478
479         _bt_unregister_osp_server_in_agent(BT_RFCOMM_SERVER,info->uuid);
480         _bt_unregister_profile(info->path);
481
482         rfcomm_nodes = g_slist_remove(rfcomm_nodes, info);
483         free_rfcomm_info(info);
484
485         return BLUETOOTH_ERROR_NONE;
486 #else
487         BT_INIT_PARAMS();
488         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
489
490         g_array_append_vals(in_param1, &socket_fd, sizeof(int));
491
492         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_REMOVE_SOCKET,
493                 in_param1, in_param2, in_param3, in_param4, &out_param);
494
495         BT_DBG("result: %x", result);
496
497         if (result == BLUETOOTH_ERROR_NONE) {
498                 _bt_remove_server(socket_fd);
499         }
500
501         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
502
503         return result;
504 #endif
505 }
506
507 BT_EXPORT_API int bluetooth_rfcomm_remove_socket_ex(const char *uuid)
508 {
509 #ifdef RFCOMM_DIRECT
510         rfcomm_info_t *info;
511
512         BT_CHECK_ENABLED(return);
513
514         if (_bt_check_privilege(BT_BLUEZ_SERVICE, BT_RFCOMM_REMOVE_SOCKET)
515                 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
516                 BT_ERR("Don't have a privilege to use this API");
517                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
518         }
519
520         BT_INFO("<<<<<<<<< RFCOMM Remove socket request from app, uuid=[%s] >>>>>>>>>>>", uuid);
521
522         info = __find_rfcomm_info_with_uuid(uuid);
523         if (info == NULL)
524                 return BLUETOOTH_ERROR_INVALID_PARAM;
525
526         _bt_unregister_osp_server_in_agent(BT_RFCOMM_SERVER, info->uuid);
527         _bt_unregister_profile(info->path);
528
529         rfcomm_nodes = g_slist_remove(rfcomm_nodes, info);
530         free_rfcomm_info(info);
531
532         return BLUETOOTH_ERROR_NONE;
533 #else
534         return BLUETOOTH_ERROR_NOT_SUPPORT;
535 #endif
536 }
537
538 BT_EXPORT_API int bluetooth_rfcomm_server_disconnect(int socket_fd)
539 {
540 #ifdef RFCOMM_DIRECT
541         rfcomm_info_t *info;
542
543         char address[20];
544
545         BT_INFO(">>>>>>>>RFCOMM server disconnect request from APP>>>>>>>>>");
546         if (socket_fd < 0) {
547                 BT_ERR("Invalid FD");
548                 return BLUETOOTH_ERROR_INVALID_PARAM;
549         }
550
551         info = __find_rfcomm_info_with_fd(socket_fd);
552         if (info == NULL)
553                 return BLUETOOTH_ERROR_INVALID_PARAM;
554
555         if (info->data_io == NULL)
556                 return BLUETOOTH_ERROR_NOT_CONNECTED;
557
558         g_io_channel_shutdown(info->data_io, TRUE, NULL);
559         g_io_channel_unref(info->data_io);
560         info->data_io = NULL;
561
562         _bt_convert_addr_type_to_string(address, info->addr.addr);
563         BT_DBG("Address %s", address);
564         _bt_disconnect_profile(address, info->uuid, NULL,NULL);
565
566         info->disconnect_idle_id = g_idle_add((GSourceFunc)
567                                                         __rfcomm_server_disconnect, info);
568         BT_DBG("-");
569
570         return BLUETOOTH_ERROR_NONE;
571 #else
572         int result;
573
574         BT_CHECK_ENABLED(return);
575
576         BT_INIT_PARAMS();
577         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
578
579         g_array_append_vals(in_param1, &socket_fd, sizeof(int));
580
581         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_SOCKET_DISCONNECT,
582                 in_param1, in_param2, in_param3, in_param4, &out_param);
583
584         BT_DBG("result: %x", result);
585
586         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
587
588         return result;
589 #endif
590 }
591
592 BT_EXPORT_API gboolean bluetooth_rfcomm_is_server_uuid_available(const char *uuid)
593 {
594         int result;
595         gboolean available = TRUE;
596         char uuid_str[BLUETOOTH_UUID_STRING_MAX];
597
598         retv_if(uuid == NULL, FALSE);
599         retv_if(bluetooth_check_adapter() ==
600                                 BLUETOOTH_ADAPTER_DISABLED, FALSE);
601
602         BT_INIT_PARAMS();
603         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
604
605         g_strlcpy(uuid_str, uuid, sizeof(uuid_str));
606         g_array_append_vals(in_param1, uuid_str, BLUETOOTH_UUID_STRING_MAX);
607
608         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_IS_UUID_AVAILABLE,
609                 in_param1, in_param2, in_param3, in_param4, &out_param);
610
611         BT_DBG("result: %x", result);
612
613         if (result == BLUETOOTH_ERROR_NONE) {
614                 available = g_array_index(out_param, gboolean, 0);
615         }
616
617         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
618
619         BT_DBG("available: %d", available);
620
621         return available;
622 }
623
624 BT_EXPORT_API int bluetooth_rfcomm_server_is_connected(const bluetooth_device_address_t *device_address, gboolean *connected)
625 {
626         GSList *l;
627         rfcomm_info_t *info;
628         char connected_addr[BT_ADDRESS_STRING_SIZE] = { 0 };
629         char input_addr[BT_ADDRESS_STRING_SIZE] = { 0 };
630
631         BT_CHECK_PARAMETER(device_address, return);
632         BT_CHECK_PARAMETER(connected, return);
633
634         _bt_convert_addr_type_to_string(input_addr, (unsigned char *)device_address->addr);
635
636         *connected = FALSE;
637
638         for (l = rfcomm_nodes; l != NULL; l = l->next) {
639                 info = l->data;
640
641                 if (info == NULL)
642                         continue;
643                 _bt_convert_addr_type_to_string(connected_addr, info->addr.addr);
644
645                 if (g_strcmp0(connected_addr, input_addr) == 0) {
646                         *connected = TRUE;
647                         return BLUETOOTH_ERROR_NONE;
648                 }
649         }
650
651         return BLUETOOTH_ERROR_NONE;
652 }
653
654 BT_EXPORT_API int bluetooth_rfcomm_listen_and_accept(int socket_fd, int max_pending_connection)
655 {
656 #ifdef RFCOMM_DIRECT
657         rfcomm_info_t *info;
658 #else
659         int result;
660         gboolean native_service = TRUE;
661 #endif
662
663         BT_CHECK_ENABLED(return);
664         if (socket_fd < 0) {
665                 BT_ERR("Invalid FD");
666                 return BLUETOOTH_ERROR_INVALID_PARAM;
667         }
668
669 #ifdef RFCOMM_DIRECT
670         BT_INFO("<<<<<<<<< RFCOMM Listen & accept from app >>>>>>>>>>>");
671
672         info = __find_rfcomm_info_with_id(socket_fd);
673         if (info == NULL)
674                 return BLUETOOTH_ERROR_INVALID_PARAM;
675
676         bt_register_profile_info_t profile_info;
677         int result;
678
679         profile_info.authentication = TRUE;
680         profile_info.authorization = TRUE;
681         profile_info.obj_path = info->path;
682         profile_info.role = NULL;
683         profile_info.service = info->uuid;
684         profile_info.uuid = info->uuid;
685
686         BT_INFO("uuid %s", profile_info.uuid);
687         result = _bt_register_profile(&profile_info, TRUE);
688
689         return result;
690 #else
691         BT_INIT_PARAMS();
692         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
693
694         g_array_append_vals(in_param1, &socket_fd, sizeof(int));
695         g_array_append_vals(in_param2, &max_pending_connection, sizeof(int));
696         g_array_append_vals(in_param3, &native_service, sizeof(gboolean));
697
698         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_LISTEN,
699                 in_param1, in_param2, in_param3, in_param4, &out_param);
700
701         BT_DBG("result: %x", result);
702
703         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
704
705         return result;
706 #endif
707 }
708
709 BT_EXPORT_API int bluetooth_rfcomm_listen_and_accept_ex(const char *uuid, int max_pending_connection, const char *bus_name, const char *path)
710 {
711 #ifdef RFCOMM_DIRECT
712         rfcomm_info_t *info;
713
714         BT_CHECK_ENABLED(return);
715
716         BT_INFO("<<<<<<<<< RFCOMM Listen & accept from app >>>>>>>>>>>");
717
718         info = __find_rfcomm_info_with_uuid(uuid);
719         if (info == NULL)
720                 return BLUETOOTH_ERROR_INVALID_PARAM;
721
722         bt_register_profile_info_t profile_info;
723         int result;
724
725         profile_info.authentication = TRUE;
726         profile_info.authorization = TRUE;
727         profile_info.obj_path = info->path;
728         profile_info.role = NULL;
729         profile_info.service = info->uuid;
730         profile_info.uuid = info->uuid;
731
732         BT_INFO("uuid %s", profile_info.uuid);
733         result = _bt_register_profile_ex(&profile_info, TRUE, bus_name, path);
734
735         return result;
736 #else
737         return BLUETOOTH_ERROR_NOT_SUPPORT;
738 #endif
739 }
740
741 BT_EXPORT_API int bluetooth_rfcomm_listen(int socket_fd, int max_pending_connection)
742 {
743 #ifdef RFCOMM_DIRECT
744         rfcomm_info_t *info;
745 #else
746         int result;
747         gboolean native_service = FALSE;
748 #endif
749
750         BT_CHECK_ENABLED(return);
751         if (socket_fd < 0) {
752                 BT_ERR("Invalid FD");
753                 return BLUETOOTH_ERROR_INVALID_PARAM;
754         }
755
756 #ifdef RFCOMM_DIRECT
757         BT_INFO("<<<<<<<<< RFCOMM Listen >>>>>>>>>>>");
758
759         info = __find_rfcomm_info_with_id(socket_fd);
760         if (info == NULL)
761                 return BLUETOOTH_ERROR_INVALID_PARAM;
762
763         bt_register_profile_info_t profile_info;
764         int result;
765
766         profile_info.authentication = TRUE;
767         profile_info.authorization = TRUE;
768         profile_info.obj_path = info->path;
769         profile_info.role = NULL;
770         profile_info.service = info->uuid;
771         profile_info.uuid = info->uuid;
772         BT_INFO("UUID %s", info->uuid);
773         BT_INFO("PATH %s", info->path);
774         result = _bt_register_profile_platform(&profile_info, TRUE);
775         if (result != BLUETOOTH_ERROR_NONE)
776                 return result;
777
778         return _bt_register_osp_server_in_agent(BT_RFCOMM_SERVER, info->uuid,
779                                                 info->path, socket_fd);
780
781 #else
782         BT_INIT_PARAMS();
783         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
784
785         g_array_append_vals(in_param1, &socket_fd, sizeof(int));
786         g_array_append_vals(in_param2, &max_pending_connection, sizeof(int));
787         g_array_append_vals(in_param3, &native_service, sizeof(gboolean));
788
789         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_LISTEN,
790                 in_param1, in_param2, in_param3, in_param4, &out_param);
791
792         BT_DBG("result: %x", result);
793
794         if (result == BLUETOOTH_ERROR_NONE) {
795                 _bt_add_server(socket_fd);
796         }
797
798         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
799
800         return result;
801 #endif
802 }
803
804 BT_EXPORT_API int bluetooth_rfcomm_accept_connection(int server_fd)
805 {
806         int result;
807
808         BT_CHECK_ENABLED(return);
809         if (server_fd < 0) {
810                 BT_ERR("Invalid FD");
811                 return BLUETOOTH_ERROR_INVALID_PARAM;
812         }
813
814         BT_INIT_PARAMS();
815         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
816
817         g_array_append_vals(in_param1, &server_fd, sizeof(int));
818
819         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_ACCEPT_CONNECTION,
820                 in_param1, in_param2, in_param3, in_param4, &out_param);
821
822         BT_DBG("result: %x", result);
823
824         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
825
826         return result;
827 }
828
829 BT_EXPORT_API int bluetooth_rfcomm_reject_connection(int server_fd)
830 {
831         int result;
832
833         BT_CHECK_ENABLED(return);
834
835         if (server_fd < 0) {
836                 BT_ERR("Invalid FD");
837                 return BLUETOOTH_ERROR_INVALID_PARAM;
838         }
839
840         BT_INFO("+");
841
842         BT_INIT_PARAMS();
843         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
844
845         g_array_append_vals(in_param1, &server_fd, sizeof(int));
846
847         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_REJECT_CONNECTION,
848                 in_param1, in_param2, in_param3, in_param4, &out_param);
849
850         BT_DBG("result: %x", result);
851
852         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
853
854         return result;
855 }
856