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