Merge the code from tizen_2.4
[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         if (socket_fd < 0) {
474                 BT_ERR("Invalid FD");
475                 return BLUETOOTH_ERROR_INVALID_PARAM;
476         }
477
478 #ifdef RFCOMM_DIRECT
479         BT_INFO("<<<<<<<<< RFCOMM Remove socket request from app, fd=[%d] >>>>>>>>>>>", socket_fd);
480
481         info = __find_rfcomm_info_with_id(socket_fd);
482         if (info == NULL)
483                 return BLUETOOTH_ERROR_INVALID_PARAM;
484
485         _bt_unregister_osp_server_in_agent(BT_RFCOMM_SERVER,info->uuid);
486         _bt_unregister_profile(info->path);
487
488         rfcomm_nodes = g_slist_remove(rfcomm_nodes, info);
489         free_rfcomm_info(info);
490
491         return BLUETOOTH_ERROR_NONE;
492 #else
493         BT_INIT_PARAMS();
494         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
495
496         g_array_append_vals(in_param1, &socket_fd, sizeof(int));
497
498         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_REMOVE_SOCKET,
499                 in_param1, in_param2, in_param3, in_param4, &out_param);
500
501         BT_DBG("result: %x", result);
502
503         if (result == BLUETOOTH_ERROR_NONE) {
504                 _bt_remove_server(socket_fd);
505         }
506
507         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
508
509         return result;
510 #endif
511 }
512
513 BT_EXPORT_API int bluetooth_rfcomm_remove_socket_ex(const char *uuid)
514 {
515 #ifdef RFCOMM_DIRECT
516         rfcomm_info_t *info;
517
518         BT_CHECK_ENABLED(return);
519
520         if (_bt_check_privilege(BT_BLUEZ_SERVICE, BT_RFCOMM_REMOVE_SOCKET)
521                 == BLUETOOTH_ERROR_PERMISSION_DEINED) {
522                 BT_ERR("Don't have a privilege to use this API");
523                 return BLUETOOTH_ERROR_PERMISSION_DEINED;
524         }
525
526         BT_INFO("<<<<<<<<< RFCOMM Remove socket request from app, uuid=[%s] >>>>>>>>>>>", uuid);
527
528         info = __find_rfcomm_info_with_uuid(uuid);
529         if (info == NULL)
530                 return BLUETOOTH_ERROR_INVALID_PARAM;
531
532         _bt_unregister_osp_server_in_agent(BT_RFCOMM_SERVER, info->uuid);
533         _bt_unregister_profile(info->path);
534
535         rfcomm_nodes = g_slist_remove(rfcomm_nodes, info);
536         free_rfcomm_info(info);
537
538         return BLUETOOTH_ERROR_NONE;
539 #else
540         return BLUETOOTH_ERROR_NOT_SUPPORT;
541 #endif
542 }
543
544 BT_EXPORT_API int bluetooth_rfcomm_server_disconnect(int socket_fd)
545 {
546 #ifdef RFCOMM_DIRECT
547         rfcomm_info_t *info;
548
549         char address[20];
550
551         BT_INFO(">>>>>>>>RFCOMM server disconnect request from APP>>>>>>>>>");
552         if (socket_fd < 0) {
553                 BT_ERR("Invalid FD");
554                 return BLUETOOTH_ERROR_INVALID_PARAM;
555         }
556
557         info = __find_rfcomm_info_with_fd(socket_fd);
558         if (info == NULL)
559                 return BLUETOOTH_ERROR_INVALID_PARAM;
560
561         if (info->data_io == NULL)
562                 return BLUETOOTH_ERROR_NOT_CONNECTED;
563
564         g_io_channel_shutdown(info->data_io, TRUE, NULL);
565         g_io_channel_unref(info->data_io);
566         info->data_io = NULL;
567
568         _bt_convert_addr_type_to_string(address, info->addr.addr);
569         BT_DBG("Address %s", address);
570         _bt_disconnect_profile(address, info->uuid, NULL,NULL);
571
572         info->disconnect_idle_id = g_idle_add((GSourceFunc)
573                                                         __rfcomm_server_disconnect, info);
574         BT_DBG("-");
575
576         return BLUETOOTH_ERROR_NONE;
577 #else
578         int result;
579
580         BT_CHECK_ENABLED(return);
581
582         BT_INIT_PARAMS();
583         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
584
585         g_array_append_vals(in_param1, &socket_fd, sizeof(int));
586
587         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_SOCKET_DISCONNECT,
588                 in_param1, in_param2, in_param3, in_param4, &out_param);
589
590         BT_DBG("result: %x", result);
591
592         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
593
594         return result;
595 #endif
596 }
597
598 BT_EXPORT_API gboolean bluetooth_rfcomm_is_server_uuid_available(const char *uuid)
599 {
600         int result;
601         gboolean available = TRUE;
602         char uuid_str[BLUETOOTH_UUID_STRING_MAX];
603
604         retv_if(uuid == NULL, FALSE);
605         retv_if(bluetooth_check_adapter() ==
606                                 BLUETOOTH_ADAPTER_DISABLED, FALSE);
607
608         BT_INIT_PARAMS();
609         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
610
611         g_strlcpy(uuid_str, uuid, sizeof(uuid_str));
612         g_array_append_vals(in_param1, uuid_str, BLUETOOTH_UUID_STRING_MAX);
613
614         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_IS_UUID_AVAILABLE,
615                 in_param1, in_param2, in_param3, in_param4, &out_param);
616
617         BT_DBG("result: %x", result);
618
619         if (result == BLUETOOTH_ERROR_NONE) {
620                 available = g_array_index(out_param, gboolean, 0);
621         }
622
623         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
624
625         BT_DBG("available: %d", available);
626
627         return available;
628 }
629
630 BT_EXPORT_API int bluetooth_rfcomm_server_is_connected(const bluetooth_device_address_t *device_address, gboolean *connected)
631 {
632         GSList *l;
633         rfcomm_info_t *info;
634         char connected_addr[BT_ADDRESS_STRING_SIZE] = { 0 };
635         char input_addr[BT_ADDRESS_STRING_SIZE] = { 0 };
636
637         BT_CHECK_PARAMETER(device_address, return);
638         BT_CHECK_PARAMETER(connected, return);
639
640         _bt_convert_addr_type_to_string(input_addr, (unsigned char *)device_address->addr);
641
642         *connected = FALSE;
643
644         for (l = rfcomm_nodes; l != NULL; l = l->next) {
645                 info = l->data;
646
647                 if (info == NULL)
648                         continue;
649                 _bt_convert_addr_type_to_string(connected_addr, info->addr.addr);
650
651                 if (g_strcmp0(connected_addr, input_addr) == 0) {
652                         *connected = TRUE;
653                         return BLUETOOTH_ERROR_NONE;
654                 }
655         }
656
657         return BLUETOOTH_ERROR_NONE;
658 }
659
660 BT_EXPORT_API int bluetooth_rfcomm_listen_and_accept(int socket_fd, int max_pending_connection)
661 {
662 #ifdef RFCOMM_DIRECT
663         rfcomm_info_t *info;
664 #else
665         int result;
666         gboolean native_service = TRUE;
667 #endif
668
669         BT_CHECK_ENABLED(return);
670         if (socket_fd < 0) {
671                 BT_ERR("Invalid FD");
672                 return BLUETOOTH_ERROR_INVALID_PARAM;
673         }
674
675 #ifdef RFCOMM_DIRECT
676         BT_INFO("<<<<<<<<< RFCOMM Listen & accept from app >>>>>>>>>>>");
677
678         info = __find_rfcomm_info_with_id(socket_fd);
679         if (info == NULL)
680                 return BLUETOOTH_ERROR_INVALID_PARAM;
681
682         bt_register_profile_info_t profile_info;
683         int result;
684
685         profile_info.authentication = TRUE;
686         profile_info.authorization = TRUE;
687         profile_info.obj_path = info->path;
688         profile_info.role = NULL;
689         profile_info.service = info->uuid;
690         profile_info.uuid = info->uuid;
691
692         BT_INFO("uuid %s", profile_info.uuid);
693         result = _bt_register_profile(&profile_info, TRUE);
694
695         return result;
696 #else
697         BT_INIT_PARAMS();
698         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
699
700         g_array_append_vals(in_param1, &socket_fd, sizeof(int));
701         g_array_append_vals(in_param2, &max_pending_connection, sizeof(int));
702         g_array_append_vals(in_param3, &native_service, sizeof(gboolean));
703
704         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_LISTEN,
705                 in_param1, in_param2, in_param3, in_param4, &out_param);
706
707         BT_DBG("result: %x", result);
708
709         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
710
711         return result;
712 #endif
713 }
714
715 BT_EXPORT_API int bluetooth_rfcomm_listen_and_accept_ex(const char *uuid, int max_pending_connection, const char *bus_name, const char *path)
716 {
717 #ifdef RFCOMM_DIRECT
718         rfcomm_info_t *info;
719
720         BT_CHECK_ENABLED(return);
721
722         BT_INFO("<<<<<<<<< RFCOMM Listen & accept from app >>>>>>>>>>>");
723
724         info = __find_rfcomm_info_with_uuid(uuid);
725         if (info == NULL)
726                 return BLUETOOTH_ERROR_INVALID_PARAM;
727
728         bt_register_profile_info_t profile_info;
729         int result;
730
731         profile_info.authentication = TRUE;
732         profile_info.authorization = TRUE;
733         profile_info.obj_path = info->path;
734         profile_info.role = NULL;
735         profile_info.service = info->uuid;
736         profile_info.uuid = info->uuid;
737
738         BT_INFO("uuid %s", profile_info.uuid);
739         result = _bt_register_profile_ex(&profile_info, TRUE, bus_name, path);
740
741         return result;
742 #else
743         return BLUETOOTH_ERROR_NOT_SUPPORT;
744 #endif
745 }
746
747 BT_EXPORT_API int bluetooth_rfcomm_listen(int socket_fd, int max_pending_connection)
748 {
749 #ifdef RFCOMM_DIRECT
750         rfcomm_info_t *info;
751 #else
752         int result;
753         gboolean native_service = FALSE;
754 #endif
755
756         BT_CHECK_ENABLED(return);
757         if (socket_fd < 0) {
758                 BT_ERR("Invalid FD");
759                 return BLUETOOTH_ERROR_INVALID_PARAM;
760         }
761
762 #ifdef RFCOMM_DIRECT
763         BT_INFO("<<<<<<<<< RFCOMM Listen >>>>>>>>>>>");
764
765         info = __find_rfcomm_info_with_id(socket_fd);
766         if (info == NULL)
767                 return BLUETOOTH_ERROR_INVALID_PARAM;
768
769         bt_register_profile_info_t profile_info;
770         int result;
771
772         profile_info.authentication = TRUE;
773         profile_info.authorization = TRUE;
774         profile_info.obj_path = info->path;
775         profile_info.role = NULL;
776         profile_info.service = info->uuid;
777         profile_info.uuid = info->uuid;
778         BT_INFO("UUID %s", info->uuid);
779         BT_INFO("PATH %s", info->path);
780         result = _bt_register_profile_platform(&profile_info, TRUE);
781         if (result != BLUETOOTH_ERROR_NONE)
782                 return result;
783
784         return _bt_register_osp_server_in_agent(BT_RFCOMM_SERVER, info->uuid,
785                                                 info->path, socket_fd);
786
787 #else
788         BT_INIT_PARAMS();
789         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
790
791         g_array_append_vals(in_param1, &socket_fd, sizeof(int));
792         g_array_append_vals(in_param2, &max_pending_connection, sizeof(int));
793         g_array_append_vals(in_param3, &native_service, sizeof(gboolean));
794
795         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_LISTEN,
796                 in_param1, in_param2, in_param3, in_param4, &out_param);
797
798         BT_DBG("result: %x", result);
799
800         if (result == BLUETOOTH_ERROR_NONE) {
801                 _bt_add_server(socket_fd);
802         }
803
804         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
805
806         return result;
807 #endif
808 }
809
810 BT_EXPORT_API int bluetooth_rfcomm_accept_connection(int server_fd)
811 {
812         int result;
813
814         BT_CHECK_ENABLED(return);
815         if (server_fd < 0) {
816                 BT_ERR("Invalid FD");
817                 return BLUETOOTH_ERROR_INVALID_PARAM;
818         }
819
820         BT_INIT_PARAMS();
821         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
822
823         g_array_append_vals(in_param1, &server_fd, sizeof(int));
824
825         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_ACCEPT_CONNECTION,
826                 in_param1, in_param2, in_param3, in_param4, &out_param);
827
828         BT_DBG("result: %x", result);
829
830         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
831
832         return result;
833 }
834
835 BT_EXPORT_API int bluetooth_rfcomm_reject_connection(int server_fd)
836 {
837         int result;
838
839         BT_CHECK_ENABLED(return);
840
841         if (server_fd < 0) {
842                 BT_ERR("Invalid FD");
843                 return BLUETOOTH_ERROR_INVALID_PARAM;
844         }
845
846         BT_INFO("+");
847
848         BT_INIT_PARAMS();
849         BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
850
851         g_array_append_vals(in_param1, &server_fd, sizeof(int));
852
853         result = _bt_send_request(BT_BLUEZ_SERVICE, BT_RFCOMM_REJECT_CONNECTION,
854                 in_param1, in_param2, in_param3, in_param4, &out_param);
855
856         BT_DBG("result: %x", result);
857
858         BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
859
860         return result;
861 }
862