Fix dlog format error
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-rfcomm-dbus-handler.c
1 /*
2  * Bluetooth-frwk
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Atul Kumar Rai <a.rai@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *              http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <stdbool.h>
25 #include <string.h>
26 #include <sys/types.h>
27 #include <sys/socket.h>
28
29 #include <glib.h>
30 #include <gio/gio.h>
31 #include <dlog.h>
32 #include <vconf.h>
33
34 #include "bt-hal-rfcomm-dbus-handler.h"
35 #include "bt-hal-dbus-common-utils.h"
36
37 #define BT_HAL_RFCOMM_ID_MAX 245
38 #define BT_HAL_RFCOMM_MAX_BUFFER_SIZE 1024
39
40 typedef struct {
41         char remote_addr[BT_HAL_ADDRESS_STRING_SIZE];
42         int hal_fd;
43         unsigned int hal_watch;
44         int stack_fd;
45         unsigned int bt_watch;
46 } rfcomm_conn_info_t;
47
48 typedef struct {
49         char uuid[BT_HAL_UUID_STRING_LEN];
50         char *device_path;
51         char *obj_path;
52         int object_id;
53         int id;
54         rfcomm_conn_info_t *conn_info;
55 } rfcomm_cb_data_t;
56
57 typedef struct {
58         char uuid[BT_HAL_UUID_STRING_LEN];
59         char *svc_name;
60         char *obj_path;
61         int object_id;
62         int id;
63         int server_fd;
64         unsigned int server_watch;
65         GSList *conn_list;
66 } rfcomm_server_data_t;
67
68 static GSList *rfcomm_clients;
69 static GSList *rfcomm_servers;
70 static int latest_id = -1;
71 static gboolean id_used[BT_HAL_RFCOMM_ID_MAX];
72
73 int __rfcomm_assign_id(void)
74 {
75         int index;
76
77         DBG("latest_id: %d", latest_id);
78
79         index = latest_id + 1;
80         if (index >= BT_HAL_RFCOMM_ID_MAX)
81                 index = 0;
82
83         DBG("index: %d", index);
84
85         while (id_used[index] == TRUE) {
86                 if (index == latest_id) {
87                         /* No available ID */
88                         ERR("All request ID is used");
89                         return -1;
90                 }
91
92                 index++;
93                 if (index >= BT_HAL_RFCOMM_ID_MAX)
94                         index = 0;
95         }
96
97         latest_id = index;
98         id_used[index] = TRUE;
99         DBG("Assigned Id: %d", latest_id);
100
101         return latest_id;
102 }
103
104 void __rfcomm_delete_id(int id)
105 {
106         if (id >= BT_HAL_RFCOMM_ID_MAX || id < 0) {
107                 ERR("Invalid id %d", id);
108                 return;
109         }
110
111         id_used[id] = FALSE;
112         latest_id = id - 1;
113         DBG("id: %d, latest_id: %d", id, latest_id);
114 }
115
116 /*************************** RFCOMM Client Implementation ***************************/
117 static rfcomm_cb_data_t *__find_rfcomm_info_from_path(const char *path)
118 {
119         GSList *l;
120
121         for (l = rfcomm_clients; l != NULL; l = l->next) {
122                 rfcomm_cb_data_t *info = l->data;
123
124                 if (info != NULL)
125                         if (g_strcmp0(info->obj_path, path) == 0)
126                                 return info;
127         }
128
129         return NULL;
130 }
131
132 static void __bt_free_conn(rfcomm_conn_info_t *conn)
133 {
134         DBG("+");
135
136         if (conn == NULL)
137                 return;
138
139         if (0 < conn->hal_fd)
140                 close(conn->hal_fd);
141
142         if (conn->hal_watch > 0) {
143                 g_source_remove(conn->hal_watch);
144                 conn->hal_watch = 0;
145         }
146
147         if (0 < conn->stack_fd)
148                 close(conn->stack_fd);
149
150         if (conn->bt_watch > 0) {
151                 g_source_remove(conn->bt_watch);
152                 conn->bt_watch = 0;
153         }
154
155         g_free(conn);
156         DBG("-");
157 }
158
159 static void __bt_free_cb_data(rfcomm_cb_data_t *cb_data)
160 {
161         DBG("+");
162
163         if (cb_data->id >= 0)
164                 __rfcomm_delete_id(cb_data->id);
165
166         if (cb_data->object_id > 0)
167                 _bt_hal_unregister_gdbus_object(cb_data->object_id);
168
169         if (cb_data->obj_path) {
170                 INFO("Unregister profile");
171                 _bt_hal_unregister_profile(cb_data->obj_path);
172         }
173
174         g_free(cb_data->obj_path);
175
176         g_free(cb_data->device_path);
177         g_free(cb_data);
178
179         DBG("-");
180 }
181
182 static void __rfcomm_cb_data_remove(rfcomm_cb_data_t *info)
183 {
184         if (!info) {
185                 ERR("info == NULL");
186                 return;
187         }
188
189         rfcomm_clients = g_slist_remove(rfcomm_clients, info);
190         __bt_free_conn(info->conn_info);
191         __bt_free_cb_data(info);
192 }
193
194 static int write_all(int fd, unsigned char *buf, int len)
195 {
196         int sent = 0;
197
198         while (len > 0) {
199                 int written;
200
201                 written = write(fd, buf, len);
202                 if (written < 0) {
203                         if (errno == EINTR || errno == EAGAIN)
204                                 continue;
205                         return -1;
206                 }
207
208                 if (!written)
209                         return 0;
210
211                 len -= written; buf += written; sent += written;
212         }
213
214         return sent;
215 }
216
217 static gboolean app_event_cb(GIOChannel *io, GIOCondition cond, gpointer data)
218 {
219         gsize len;
220         int sent;
221         rfcomm_cb_data_t *info = data;
222         rfcomm_conn_info_t *conn_info;
223         unsigned char buff[BT_HAL_RFCOMM_MAX_BUFFER_SIZE];
224         GError *err = NULL;
225         int fd;
226         char err_msg[256] = {0, };
227
228         DBG("+");
229         fd = g_io_channel_unix_get_fd(io);
230         conn_info = info->conn_info;
231
232         if (cond & G_IO_HUP) {
233                 ERR("Socket %d hang up", fd);
234                 goto fail;
235         }
236
237         if (cond & (G_IO_ERR | G_IO_NVAL)) {
238                 ERR("Socket %d error", fd);
239                 goto fail;
240         }
241
242         if (!conn_info) {
243                 ERR("conn_info is NULL");
244                 return TRUE;
245         }
246
247         /* Read data from application */
248         if (g_io_channel_read_chars(io, (gchar *)buff,
249                         BT_HAL_RFCOMM_MAX_BUFFER_SIZE,
250                         &len, &err) == G_IO_STATUS_ERROR) {
251                 if (err)
252                         ERR("IO Channel read error: %s", err->message);
253                 else
254                         ERR("IO Channel read error client");
255                 goto fail;
256         }
257
258         DBG("len: %zu", len);
259         if (0 == len) {
260                 ERR("Other end of socket is closed");
261                 goto fail;
262         }
263
264         /* Send data to remote device */
265         sent = write_all(conn_info->stack_fd, buff, len);
266         if (sent < 0) {
267                 strerror_r(errno, err_msg, sizeof(err_msg));
268                 ERR("write(): %s", err_msg);
269                 goto fail;
270         }
271
272         DBG("-");
273         return TRUE;
274 fail:
275         __rfcomm_cb_data_remove(info);
276         return FALSE;
277 }
278
279 static gboolean stack_event_cb(GIOChannel *io, GIOCondition cond, gpointer data)
280 {
281         unsigned int len;
282         int sent;
283         rfcomm_cb_data_t *info = data;
284         rfcomm_conn_info_t *conn_info;
285         unsigned char buff[BT_HAL_RFCOMM_MAX_BUFFER_SIZE];
286         GError *err = NULL;
287         int fd;
288         char err_msg[256] = {0, };
289
290         DBG("+");
291
292         fd = g_io_channel_unix_get_fd(io);
293         conn_info = info->conn_info;
294
295         if (cond & G_IO_HUP) {
296                 ERR("Socket %d hang up", fd);
297                 goto fail;
298         }
299
300         if (cond & (G_IO_ERR | G_IO_NVAL)) {
301                 ERR("Socket %d error", fd);
302                 goto fail;
303         }
304
305         if (!conn_info) {
306                 ERR("conn_info is NULL");
307                 return TRUE;
308         }
309
310         /* Read data from remote device */
311         if (g_io_channel_read_chars(io, (gchar *)buff,
312                         BT_HAL_RFCOMM_MAX_BUFFER_SIZE,
313                         (gsize *)&len, &err) == G_IO_STATUS_ERROR) {
314                 if (err)
315                         ERR("IO Channel read error: %s", err->message);
316                 else
317                         ERR("IO Channel read error client");
318                 goto fail;
319         }
320
321         DBG("len: %d", len);
322         if (0 == len) {
323                 ERR("Other end of socket is closed");
324                 goto fail;
325         }
326
327         /* Send data to application */
328         sent = write_all(conn_info->hal_fd, buff, len);
329         if (sent < 0) {
330                 strerror_r(errno, err_msg, sizeof(err_msg));
331                 ERR("write(): %s", err_msg);
332                 goto fail;
333         }
334
335         DBG("-");
336         return TRUE;
337 fail:
338         __rfcomm_cb_data_remove(info);
339         return FALSE;
340 }
341
342 static int __new_connection(const char *path, int fd, bt_bdaddr_t *addr)
343 {
344         char address[BT_HAL_ADDRESS_STRING_SIZE];
345         rfcomm_cb_data_t *info;
346         rfcomm_conn_info_t *conn_info;
347         struct hal_ev_sock_connect ev;
348         GIOCondition cond;
349         int len;
350         GIOChannel *io;
351         char err_msg[256] = {0, };
352
353         /* TODO: Temperary, later need to fill correct channel form correct place */
354         int chan = 0;
355
356         if (NULL == path || NULL == addr) {
357                 ERR("NULL == path || NULL = addr");
358                 return -1;
359         }
360
361         info = __find_rfcomm_info_from_path(path);
362         if (info == NULL)
363                 return -1;
364
365         conn_info = info->conn_info;
366         _bt_hal_convert_addr_type_to_string(address, addr->address);
367         if (conn_info == NULL) {
368                 ERR("conn_info is NULL for dev:[%s]", address);
369                 return -1;
370         }
371
372         if (write(conn_info->hal_fd, &chan, sizeof(chan)) != sizeof(chan)) {
373                 ERR("Error sending RFCOMM channel");
374                 goto fail;
375         }
376
377         conn_info->stack_fd = fd;
378         DBG("Remote address: %s, RFCOMM fd: %d", address, conn_info->stack_fd);
379
380         /* Send rfcomm connected event */
381         memset(&ev, 0, sizeof(ev));
382         ev.size = sizeof(ev);
383         memcpy(ev.bdaddr, addr->address, 6);
384         ev.status = BT_STATUS_SUCCESS;
385         len = write_all(conn_info->hal_fd, (unsigned char *)&ev, sizeof(ev));
386         if (len < 0) {
387                 strerror_r(errno, err_msg, sizeof(err_msg));
388                 ERR("%s", err_msg);
389                 goto fail;
390         }
391
392         if (len != sizeof(ev)) {
393                 ERR("Error sending connect event");
394                 goto fail;;
395         }
396
397         /* Handle events from App */
398         cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
399         io = g_io_channel_unix_new(conn_info->hal_fd);
400         conn_info->hal_watch = g_io_add_watch(io, cond, app_event_cb, info);
401         g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
402         g_io_channel_unref(io);
403
404         /* Handle rfcomm events from bluez */
405         cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
406         io = g_io_channel_unix_new(conn_info->stack_fd);
407         conn_info->bt_watch = g_io_add_watch(io, cond, stack_event_cb, info);
408         g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
409         g_io_channel_unref(io);
410
411         return 0;
412 fail:
413         __rfcomm_cb_data_remove(info);
414         return -1;
415 }
416
417 static void __bt_connect_response_cb(GDBusProxy *proxy,
418                 GAsyncResult *res, gpointer user_data)
419 {
420         GError *error = NULL;
421         rfcomm_cb_data_t *cb_data;
422
423         DBG("+");
424
425         cb_data = user_data;
426         if (cb_data == NULL) {
427                 ERR("cb_data == NULL");
428                 return;
429         }
430
431         if (!g_dbus_proxy_call_finish(proxy, res, &error)) {
432                 ERR("Error : %s \n", error->message);
433                 __rfcomm_cb_data_remove(cb_data);
434                 g_error_free(error);
435         }
436
437         if (proxy)
438                 g_object_unref(proxy);
439
440         DBG("-");
441 }
442
443 static void __bt_discover_service_response_cb(GDBusProxy *proxy,
444                 GAsyncResult *res, gpointer user_data)
445 {
446         rfcomm_cb_data_t *cb_data;
447         int ret = 0;
448         GError *err = NULL;
449         bt_hal_register_profile_info_t info = {0};
450         char dev_address[BT_HAL_ADDRESS_STRING_SIZE];
451         const char *path;
452
453         DBG("+");
454
455         cb_data = user_data;
456         if (!cb_data) {
457                 ERR("cb_data == NULL");
458                 return;
459         }
460
461         path = g_dbus_proxy_get_object_path(proxy);
462         _bt_hal_convert_device_path_to_address(path, dev_address);
463         DBG("Device Adress [%s]", dev_address);
464
465         g_dbus_proxy_call_finish(proxy, res, &err);
466         if (proxy)
467                 g_object_unref(proxy);
468         if (err != NULL) {
469                 ERR("Error occured in Proxy call [%s]\n", err->message);
470                 __rfcomm_cb_data_remove(cb_data);
471                 goto done;
472         } else {
473                 INFO("Services are Updated checking required uuid is there");
474                 /* Check here for uuid present */
475                 ret = _bt_hal_discover_service_uuids(dev_address, cb_data->uuid);
476                 if (ret == BT_STATUS_SUCCESS) {
477                         info.uuid = (char *)cb_data->uuid;
478                         info.obj_path = cb_data->obj_path;
479                         info.role = "client";
480
481                         ret = _bt_hal_register_profile(&info, FALSE);
482                         if (ret < 0)
483                                 DBG("Error: register profile");
484                         ret = _bt_hal_connect_profile(dev_address, cb_data->uuid,
485                                         __bt_connect_response_cb, cb_data);
486                         if (ret != BT_STATUS_SUCCESS) {
487                                 ERR("ConnectProfile failed");
488                                 __rfcomm_cb_data_remove(cb_data);
489                                 goto done;
490                         }
491                 } else {
492                         ERR("remote uuid not found");
493                         __rfcomm_cb_data_remove(cb_data);
494                 }
495         }
496 done:
497         if (err)
498                 g_clear_error(&err);
499 }
500
501 static rfcomm_cb_data_t *__get_rfcomm_cb_data(char *remote_uuid)
502 {
503         int id;
504         int object_id;
505         char *path;
506         rfcomm_cb_data_t *cb_data;
507
508         DBG("+");
509
510         id = __rfcomm_assign_id();
511         if (id < 0) {
512                 ERR("__rfcomm_assign_id failed");
513                 return NULL;
514         }
515
516         path = g_strdup_printf("/org/socket/client/%d/%d", getpid(), id);
517         object_id = _bt_hal_register_new_gdbus_object(path, __new_connection);
518         if (object_id < 0) {
519                 ERR("_bt_hal_register_new_gdbus_object failed");
520                 g_free(path);
521                 __rfcomm_delete_id(id);
522                 return NULL;
523         }
524
525         cb_data = g_malloc0(sizeof(rfcomm_cb_data_t));
526         g_strlcpy(cb_data->uuid, remote_uuid, BT_HAL_UUID_STRING_LEN);
527         cb_data->obj_path = path;
528         cb_data->object_id = object_id;
529         cb_data->id = id;
530
531         DBG("-");
532         return cb_data;
533 }
534
535 static rfcomm_conn_info_t *__rfcomm_create_conn_info(char *addr, int *sock)
536 {
537         int fds[2] = {-1, -1};
538         rfcomm_conn_info_t *conn;
539         char err_msg[256] = {0, };
540
541         if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
542                 strerror_r(errno, err_msg, sizeof(err_msg));
543                 ERR("socketpair(): %s", err_msg);
544                 *sock = -1;
545                 return NULL;
546         }
547
548         conn = g_malloc0(sizeof(rfcomm_conn_info_t));
549         g_strlcpy(conn->remote_addr, addr, BT_HAL_ADDRESS_STRING_SIZE);
550         conn->hal_fd = fds[0];
551         conn->stack_fd = -1;
552         *sock = fds[1];
553
554         DBG("hal_fd: %d, sock: %d", conn->hal_fd, *sock);
555
556         return conn;
557 }
558
559 int _bt_hal_dbus_handler_rfcomm_connect(unsigned char *addr, unsigned char *uuid, int *sock)
560 {
561         int ret;
562         rfcomm_cb_data_t *cb_data;
563         rfcomm_conn_info_t *conn;
564         char remote_addr[BT_HAL_ADDRESS_STRING_SIZE];
565         char remote_uuid[BT_HAL_UUID_STRING_LEN];
566
567         if (!addr) {
568                 ERR("remote_addr is NULL");
569                 return BT_STATUS_PARM_INVALID;
570         }
571
572         if (!uuid) {
573                 ERR("remote_uuid is NULL");
574                 return BT_STATUS_PARM_INVALID;
575         }
576
577         if (!sock) {
578                 ERR("sock is NULL");
579                 return BT_STATUS_PARM_INVALID;
580         }
581
582         _bt_hal_convert_uuid_type_to_string(remote_uuid, uuid);
583         cb_data = __get_rfcomm_cb_data(remote_uuid);
584         if (!cb_data)
585                 return BT_STATUS_FAIL;
586
587         _bt_hal_convert_addr_type_to_string(remote_addr, addr);
588         DBG("Connecting to %s, uuid %s", remote_addr, remote_uuid);
589         conn = __rfcomm_create_conn_info(remote_addr, sock);
590         if (!conn) {
591                 __bt_free_cb_data(cb_data);
592                 return BT_STATUS_FAIL;
593         }
594
595         cb_data->conn_info = conn;
596         ret = _bt_hal_discover_services(remote_addr, (char *)remote_uuid,
597                         __bt_discover_service_response_cb, cb_data);
598         if (ret != BT_STATUS_SUCCESS) {
599                 ERR("Error returned while service discovery");
600                 __bt_free_conn(conn);
601                 __bt_free_cb_data(cb_data);
602                 return BT_STATUS_FAIL;
603         }
604
605         INFO("Adding callback information to rfcomm_clients");
606         rfcomm_clients = g_slist_append(rfcomm_clients, cb_data);
607
608         return BT_STATUS_SUCCESS;
609 }
610
611 /*************************** RFCOMM Server Implementation ***************************/
612 static rfcomm_server_data_t *__find_rfcomm_server_info_with_path(const gchar *path)
613 {
614         GSList *l;
615
616         for (l = rfcomm_servers; l != NULL; l = l->next) {
617                 rfcomm_server_data_t *info = l->data;
618
619                 if (g_strcmp0(info->obj_path, path) == 0)
620                         return info;
621         }
622
623         return NULL;
624 }
625
626 static rfcomm_server_data_t *__find_rfcomm_server_info_from_uuid(const char *uuid)
627 {
628         GSList *l;
629
630         for (l = rfcomm_servers; l != NULL; l = l->next) {
631                  rfcomm_server_data_t *info = l->data;
632
633                 if (g_strcmp0(info->uuid, uuid) == 0)
634                         return info;
635         }
636
637         return NULL;
638 }
639
640 static int __send_sock_fd(int sock_fd, const void *buf, int size, int send_fd)
641 {
642         ssize_t ret;
643         struct msghdr msg;
644         struct cmsghdr *cmsg;
645         struct iovec iov;
646         char cmsg_buf[CMSG_SPACE(sizeof(int))];
647         char err_msg[256] = {0, };
648
649         if (sock_fd == -1 || send_fd == -1)
650                 return -1;
651
652         memset(&msg, 0, sizeof(msg));
653         memset(cmsg_buf, 0, sizeof(cmsg_buf));
654
655         msg.msg_control = cmsg_buf;
656         msg.msg_controllen = sizeof(cmsg_buf);
657
658         cmsg = CMSG_FIRSTHDR(&msg);
659         cmsg->cmsg_level = SOL_SOCKET;
660         cmsg->cmsg_type = SCM_RIGHTS;
661         cmsg->cmsg_len = CMSG_LEN(sizeof(send_fd));
662
663         memcpy(CMSG_DATA(cmsg), &send_fd, sizeof(send_fd));
664
665         iov.iov_base = (unsigned char *) buf;
666         iov.iov_len = size;
667
668         msg.msg_iov = &iov;
669         msg.msg_iovlen = 1;
670
671         ret = sendmsg(sock_fd, &msg, MSG_NOSIGNAL);
672         if (ret < 0) {
673                 strerror_r(errno, err_msg, sizeof(err_msg));
674                 ERR("sendmsg(): sock_fd %d send_fd %d: %s",
675                                 sock_fd, send_fd, err_msg);
676         }
677
678         return ret;
679 }
680
681 int __new_server_connection(const char *path, int fd, bt_bdaddr_t *addr)
682 {
683         int ret;
684         rfcomm_server_data_t *info;
685         struct hal_ev_sock_connect ev;
686
687         DBG("%s %d", path, fd);
688
689         if (0 > fd) {
690                 ERR("Invalid socket fd received");
691                 return -1;
692         }
693
694         info = __find_rfcomm_server_info_with_path(path);
695         if (info == NULL) {
696                 ERR("rfcomm server info not found");
697                 return -1;
698         }
699
700         /* Send rfcomm client connected event */
701         memset(&ev, 0, sizeof(ev));
702         ev.size = sizeof(ev);
703         memcpy(ev.bdaddr, addr->address, 6);
704         ev.status = BT_STATUS_SUCCESS;
705         ret = __send_sock_fd(info->server_fd, (void *)&ev, sizeof(ev), fd);
706         if (ret < 0) {
707                 ERR("Error sending connect event");
708                 close(fd);
709                 return -1;
710         }
711
712         /* Remove local reference to client socket fd */
713         close(fd);
714         return 0;
715 }
716
717 static void __free_rfcomm_server_data(rfcomm_server_data_t *data)
718 {
719         DBG("+");
720
721         if (!data) {
722                 ERR("server data is NULL");
723                 return;
724         }
725
726         if (data->id >= 0)
727                 __rfcomm_delete_id(data->id);
728
729         if (data->object_id > 0)
730                 _bt_hal_unregister_gdbus_object(data->object_id);
731
732         if (data->obj_path) {
733                 INFO("Unregister profile");
734                 _bt_hal_unregister_profile(data->obj_path);
735         }
736
737         if (0 < data->server_fd)
738                 close(data->server_fd);
739
740         if (data->server_watch > 0) {
741                 g_source_remove(data->server_watch);
742                 data->server_watch = 0;
743         }
744
745         g_free(data->obj_path);
746         g_free(data->svc_name);
747         g_free(data);
748
749         DBG("-");
750 }
751
752 static void __remove_rfcomm_server(rfcomm_server_data_t *data)
753 {
754
755         DBG("+");
756
757         rfcomm_servers = g_slist_remove(rfcomm_servers, data);
758         __free_rfcomm_server_data(data);
759
760         DBG("-");
761
762 }
763
764 static int __register_rfcomm_server(rfcomm_server_data_t *server_data)
765 {
766         int ret;
767         bt_hal_register_profile_info_t profile_info;
768
769         memset(&profile_info, 0x00, sizeof(bt_hal_register_profile_info_t));
770
771         profile_info.authentication = TRUE;
772         profile_info.authorization = TRUE;
773         profile_info.obj_path = server_data->obj_path;
774         profile_info.role = "server";
775         profile_info.service = server_data->uuid;
776         profile_info.uuid = server_data->uuid;
777
778         INFO("uuid %s, svc: %s, role: %s",
779                 profile_info.uuid, profile_info.service, profile_info.role);
780         ret = _bt_hal_register_profile(&profile_info, TRUE);
781         if (ret < 0) {
782                 ERR("Error: register profile");
783                 return BT_STATUS_FAIL;
784         }
785
786         return BT_STATUS_SUCCESS;
787 }
788
789 static rfcomm_server_data_t *__create_rfcomm_server(char *uuid, const char *svc_name, int *sock)
790 {
791         int id;
792         int ret;
793         int object_id;
794         char *path;
795         int fds[2] = {-1, -1};
796         rfcomm_server_data_t *data;
797         char err_msg[256] = {0, };
798
799         DBG("+");
800
801         data = __find_rfcomm_server_info_from_uuid(uuid);
802         if (data) {
803                 ERR("RFCOMM Server exists with UUID: %s, sv_name: %s", uuid, data->svc_name);
804                 return NULL;
805         }
806
807         id = __rfcomm_assign_id();
808         if (id < 0) {
809                 ERR("__rfcomm_assign_id failed");
810                 return NULL;
811         }
812
813         path = g_strdup_printf("/org/socket/server/%d/%d", getpid(), id);
814         object_id = _bt_hal_register_new_gdbus_object(path, __new_server_connection);
815         if (object_id < 0) {
816                 ERR("_bt_hal_register_new_gdbus_object failed");
817                 g_free(path);
818                 __rfcomm_delete_id(id);
819                 return NULL;
820         }
821
822         data = g_malloc0(sizeof(rfcomm_server_data_t));
823         g_strlcpy(data->uuid, uuid, BT_HAL_UUID_STRING_LEN);
824         data->svc_name = g_strdup(svc_name);
825         data->obj_path = path;
826         data->object_id = object_id;
827         data->id = id;
828
829         ret = __register_rfcomm_server(data);
830         if (ret != BT_STATUS_SUCCESS) {
831                 ERR("Error returned while registering service");
832                 __free_rfcomm_server_data(data);
833                 return NULL;
834         }
835
836         if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
837                 strerror_r(errno, err_msg, sizeof(err_msg));
838                 ERR("socketpair(): %s", err_msg);
839                 __free_rfcomm_server_data(data);
840                 *sock = -1;
841                 return NULL;
842         }
843
844         data->server_fd = fds[0];
845         *sock = fds[1];
846
847         DBG("server_fd: %d, sock: %d", data->server_fd, *sock);
848         return data;
849 }
850
851 static gboolean __server_event_cb(GIOChannel *io, GIOCondition cond, gpointer data)
852 {
853         gsize len;
854         rfcomm_server_data_t *info = data;
855         unsigned char buff[BT_HAL_RFCOMM_MAX_BUFFER_SIZE];
856         GError *err = NULL;
857
858         DBG("+");
859
860         if (cond & G_IO_HUP) {
861                 ERR("Socket %d hang up", info->server_fd);
862                 goto fail;
863         }
864
865         if (cond & (G_IO_ERR | G_IO_NVAL)) {
866                 ERR("Socket %d error", info->server_fd);
867                 goto fail;
868         }
869
870         /* Read data from application */
871         if (g_io_channel_read_chars(io, (gchar *)buff,
872                         BT_HAL_RFCOMM_MAX_BUFFER_SIZE,
873                         &len, &err) == G_IO_STATUS_ERROR) {
874                 if (err)
875                         ERR("IO Channel read error: %s", err->message);
876                 else
877                         ERR("IO Channel read error client");
878                 goto fail;
879         }
880
881         DBG("len: %zu", len);
882         if (0 == len) {
883                 ERR("Other end of socket is closed");
884                 goto fail;
885         }
886
887         DBG("-");
888         return TRUE;
889 fail:
890         __remove_rfcomm_server(info);
891         return FALSE;
892 }
893
894 int _bt_hal_dbus_handler_rfcomm_listen(const char *svc_name, unsigned char *uuid, int *sock)
895 {
896         int chan = 0;
897         rfcomm_server_data_t *server_data;
898         char server_uuid[BT_HAL_UUID_STRING_LEN];
899         GIOCondition cond;
900         GIOChannel *io;
901
902         if (!svc_name) {
903                 ERR("svc_name is NULL");
904                 return BT_STATUS_PARM_INVALID;
905         }
906
907         if (!uuid) {
908                 ERR("uuid is NULL");
909                 return BT_STATUS_PARM_INVALID;
910         }
911
912         if (!sock) {
913                 ERR("sock is NULL");
914                 return BT_STATUS_PARM_INVALID;
915         }
916
917         _bt_hal_convert_uuid_type_to_string(server_uuid, uuid);
918         server_data = __create_rfcomm_server(server_uuid, svc_name, sock);
919         if (!server_data)
920                 return BT_STATUS_BUSY;
921
922         /* TODO: Temperary, later need to fill correct channel form correct place */
923         if (write(server_data->server_fd, &chan, sizeof(chan)) != sizeof(chan)) {
924                 ERR("Error sending RFCOMM channel");
925                 __free_rfcomm_server_data(server_data);
926                 *sock = -1;
927                 return BT_STATUS_FAIL;
928         }
929
930         /* Rfcomm server: Handle events from Application */
931         cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
932         io = g_io_channel_unix_new(server_data->server_fd);
933         server_data->server_watch = g_io_add_watch(io, cond, __server_event_cb, server_data);
934         g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
935         g_io_channel_unref(io);
936
937         INFO("Adding server information to rfcomm_servers list");
938         rfcomm_servers = g_slist_append(rfcomm_servers, server_data);
939
940         DBG("-");
941         return BT_STATUS_SUCCESS;
942 }
943
944 gboolean _is_rfcomm_server_uuid(const char *uuid)
945 {
946         DBG("+");
947
948         if (!uuid)
949                 return FALSE;
950
951         if (NULL == __find_rfcomm_server_info_from_uuid(uuid))
952                 return FALSE;
953
954         DBG("-");
955         return TRUE;
956 }