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