4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Atul Kumar Rai <a.rai@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
26 #include <sys/types.h>
27 #include <sys/socket.h>
29 #include <dbus/dbus-glib.h>
30 #include <dbus/dbus.h>
36 #include "bt-hal-rfcomm-dbus-handler.h"
37 #include "bt-hal-dbus-common-utils.h"
39 #define BT_HAL_RFCOMM_ID_MAX 245
40 #define BT_HAL_RFCOMM_MAX_BUFFER_SIZE 1024
43 char remote_addr[BT_HAL_ADDRESS_STRING_SIZE];
45 unsigned int hal_watch;
47 unsigned int bt_watch;
51 char uuid[BT_HAL_UUID_STRING_LEN];
56 rfcomm_conn_info_t *conn_info;
59 static GSList *rfcomm_clients;
60 static int latest_id = -1;
61 static gboolean id_used[BT_HAL_RFCOMM_ID_MAX];
63 int __rfcomm_assign_id(void)
67 DBG("latest_id: %d", latest_id);
69 index = latest_id + 1;
70 if (index >= BT_HAL_RFCOMM_ID_MAX)
73 DBG("index: %d", index);
75 while (id_used[index] == TRUE) {
76 if (index == latest_id) {
78 ERR("All request ID is used");
83 if (index >= BT_HAL_RFCOMM_ID_MAX)
88 id_used[index] = TRUE;
89 DBG("Assigned Id: %d", latest_id);
94 void __rfcomm_delete_id(int id)
96 if (id >= BT_HAL_RFCOMM_ID_MAX || id < 0) {
97 ERR("Invalid id %d", id);
103 DBG("id: %d, latest_id: %d", id, latest_id);
106 static rfcomm_cb_data_t *__find_rfcomm_info_from_path(const char *path)
110 for (l = rfcomm_clients; l != NULL; l = l->next) {
111 rfcomm_cb_data_t *info = l->data;
114 if (g_strcmp0(info->obj_path, path) == 0)
121 static void __bt_free_conn(rfcomm_conn_info_t *conn)
128 if (0 < conn->hal_fd)
131 if (conn->hal_watch > 0) {
132 g_source_remove(conn->hal_watch);
136 if (0 < conn->stack_fd)
137 close(conn->stack_fd);
139 if (conn->bt_watch > 0) {
140 g_source_remove(conn->bt_watch);
148 static void __bt_free_cb_data(rfcomm_cb_data_t *cb_data)
152 if (cb_data->id >= 0)
153 __rfcomm_delete_id(cb_data->id);
155 if (cb_data->object_id > 0)
156 _bt_unregister_gdbus_object(cb_data->object_id);
158 if (cb_data->obj_path) {
159 INFO("Unregister profile");
160 _bt_unregister_profile(cb_data->obj_path);
163 g_free(cb_data->obj_path);
165 g_free(cb_data->device_path);
171 static void __rfcomm_cb_data_remove(rfcomm_cb_data_t *info)
178 rfcomm_clients = g_slist_remove(rfcomm_clients, info);
179 __bt_free_conn(info->conn_info);
180 __bt_free_cb_data(info);
183 static int write_all(int fd, unsigned char *buf, int len)
190 written = write(fd, buf, len);
192 if (errno == EINTR || errno == EAGAIN)
200 len -= written; buf += written; sent += written;
206 static gboolean app_event_cb(GIOChannel *io, GIOCondition cond, gpointer data)
210 rfcomm_cb_data_t *info = data;
211 rfcomm_conn_info_t *conn_info;
212 unsigned char buff[BT_HAL_RFCOMM_MAX_BUFFER_SIZE];
217 fd = g_io_channel_unix_get_fd(io);
218 conn_info = info->conn_info;
220 if (cond & G_IO_HUP) {
221 ERR("Socket %d hang up", fd);
225 if (cond & (G_IO_ERR | G_IO_NVAL)) {
226 ERR("Socket %d error", fd);
231 ERR("conn_info is NULL");
235 /* Read data from application */
236 if (g_io_channel_read_chars(io, (gchar *)buff,
237 BT_HAL_RFCOMM_MAX_BUFFER_SIZE,
238 &len, &err) == G_IO_STATUS_ERROR) {
240 ERR("IO Channel read error: %s", err->message);
242 ERR("IO Channel read error client");
248 ERR("Other end of socket is closed");
252 /* Send data to remote device */
253 sent = write_all(conn_info->stack_fd, buff, len);
255 ERR("write(): %s", strerror(errno));
262 __rfcomm_cb_data_remove(info);
266 static gboolean stack_event_cb(GIOChannel *io, GIOCondition cond, gpointer data)
270 rfcomm_cb_data_t *info = data;
271 rfcomm_conn_info_t *conn_info;
272 unsigned char buff[BT_HAL_RFCOMM_MAX_BUFFER_SIZE];
278 fd = g_io_channel_unix_get_fd(io);
279 conn_info = info->conn_info;
281 if (cond & G_IO_HUP) {
282 ERR("Socket %d hang up", fd);
286 if (cond & (G_IO_ERR | G_IO_NVAL)) {
287 ERR("Socket %d error", fd);
292 ERR("conn_info is NULL");
296 /* Read data from remote device */
297 if (g_io_channel_read_chars(io, (gchar *)buff,
298 BT_HAL_RFCOMM_MAX_BUFFER_SIZE,
299 &len, &err) == G_IO_STATUS_ERROR) {
301 ERR("IO Channel read error: %s", err->message);
303 ERR("IO Channel read error client");
309 ERR("Other end of socket is closed");
313 /* Send data to application */
314 sent = write_all(conn_info->hal_fd, buff, len);
316 ERR("write(): %s", strerror(errno));
323 __rfcomm_cb_data_remove(info);
327 static int __new_connection(const char *path, int fd, bt_bdaddr_t *addr)
329 char address[BT_HAL_ADDRESS_STRING_SIZE];
330 rfcomm_cb_data_t *info;
331 rfcomm_conn_info_t *conn_info;
332 struct hal_ev_sock_connect ev;
337 /* TODO: Temperary, later need to fill correct channel form correct place */
340 if (NULL == path || NULL == addr) {
341 ERR("NULL == path || NULL = addr");
345 info = __find_rfcomm_info_from_path(path);
349 conn_info = info->conn_info;
350 _bt_convert_addr_type_to_string(address, addr->address);
351 if (conn_info == NULL) {
352 ERR("conn_info is NULL for dev:[%s]", address);
356 if (write(conn_info->hal_fd, &chan, sizeof(chan)) != sizeof(chan)) {
357 ERR("Error sending RFCOMM channel");
361 conn_info->stack_fd = fd;
362 DBG("Remote address: %s, RFCOMM fd: %d", address, conn_info->stack_fd);
364 /* Send rfcomm connected event */
365 memset(&ev, 0, sizeof(ev));
366 ev.size = sizeof(ev);
367 memcpy(ev.bdaddr, addr->address, 6);
368 ev.status = BT_STATUS_SUCCESS;
369 len = write_all(conn_info->hal_fd, (unsigned char *)&ev, sizeof(ev));
371 ERR("%s", strerror(errno));
375 if (len != sizeof(ev)) {
376 ERR("Error sending connect event");
380 /* Handle events from App */
381 cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
382 io = g_io_channel_unix_new(conn_info->hal_fd);
383 conn_info->hal_watch = g_io_add_watch(io, cond, app_event_cb, info);
384 g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
385 g_io_channel_unref(io);
387 /* Handle rfcomm events from bluez */
388 cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
389 io = g_io_channel_unix_new(conn_info->stack_fd);
390 conn_info->bt_watch = g_io_add_watch(io, cond, stack_event_cb, info);
391 g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
392 g_io_channel_unref(io);
396 __rfcomm_cb_data_remove(info);
400 static void __bt_connect_response_cb(GDBusProxy *proxy,
401 GAsyncResult *res, gpointer user_data)
403 GError *error = NULL;
404 rfcomm_cb_data_t *cb_data;
409 if (cb_data == NULL) {
410 ERR("cb_data == NULL");
414 if (!g_dbus_proxy_call_finish(proxy, res, &error)) {
415 ERR("Error : %s \n", error->message);
416 __rfcomm_cb_data_remove(cb_data);
421 g_object_unref(proxy);
426 static void __bt_discover_service_response_cb(GDBusProxy *proxy,
427 GAsyncResult *res, gpointer user_data)
429 rfcomm_cb_data_t *cb_data;
432 bt_hal_register_profile_info_t info = {0};
433 char dev_address[BT_HAL_ADDRESS_STRING_SIZE];
440 ERR("cb_data == NULL");
444 path = g_dbus_proxy_get_object_path(proxy);
445 _bt_convert_device_path_to_address(path, dev_address);
446 DBG("Device Adress [%s]", dev_address);
448 g_dbus_proxy_call_finish(proxy, res, &err);
450 g_object_unref(proxy);
452 ERR("Error occured in Proxy call [%s]\n", err->message);
453 __rfcomm_cb_data_remove(cb_data);
456 INFO("Services are Updated checking required uuid is there");
457 /* Check here for uuid present */
458 ret = _bt_discover_service_uuids(dev_address, cb_data->uuid);
459 if (ret == BT_STATUS_SUCCESS) {
460 info.uuid = (char *)cb_data->uuid;
461 info.obj_path = cb_data->obj_path;
462 info.role = "client";
464 ret = _bt_register_profile(&info, FALSE);
466 DBG("Error: register profile");
467 ret = _bt_connect_profile(dev_address, cb_data->uuid,
468 __bt_connect_response_cb, cb_data);
469 if (ret != BT_STATUS_SUCCESS) {
470 ERR("ConnectProfile failed");
471 __rfcomm_cb_data_remove(cb_data);
475 ERR("remote uuid not found");
476 __rfcomm_cb_data_remove(cb_data);
484 static rfcomm_cb_data_t *__get_rfcomm_cb_data(char *remote_uuid)
489 rfcomm_cb_data_t *cb_data;
493 id = __rfcomm_assign_id();
495 ERR("__rfcomm_assign_id failed");
499 path = g_strdup_printf("/org/socket/client/%d/%d", getpid(), id);
500 object_id = _bt_register_new_gdbus_object(path, __new_connection);
502 ERR("_bt_register_new_gdbus_object failed");
503 __rfcomm_delete_id(id);
507 cb_data = g_malloc0(sizeof(rfcomm_cb_data_t));
508 g_strlcpy(cb_data->uuid, remote_uuid, BT_HAL_UUID_STRING_LEN);
509 cb_data->obj_path = path;
510 cb_data->object_id = object_id;
517 static rfcomm_conn_info_t *__rfcomm_create_conn_info(char *addr, int *sock)
519 int fds[2] = {-1, -1};
520 rfcomm_conn_info_t *conn;
522 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
523 ERR("socketpair(): %s", strerror(errno));
528 conn = g_malloc0(sizeof(rfcomm_conn_info_t));
529 g_strlcpy(conn->remote_addr, addr, BT_HAL_ADDRESS_STRING_SIZE);
530 conn->hal_fd = fds[0];
534 DBG("hal_fd: %d, sock: %d", conn->hal_fd, *sock);
539 int _bt_hal_dbus_handler_rfcomm_connect(unsigned char *addr, unsigned char *uuid, int *sock)
542 rfcomm_cb_data_t *cb_data;
543 rfcomm_conn_info_t *conn;
544 char remote_addr[BT_HAL_ADDRESS_STRING_SIZE];
545 char remote_uuid[BT_HAL_UUID_SIZE];
548 ERR("remote_addr is NULL");
549 return BT_STATUS_PARM_INVALID;
553 ERR("remote_uuid is NULL");
554 return BT_STATUS_PARM_INVALID;
559 return BT_STATUS_PARM_INVALID;
562 _bt_convert_uuid_type_to_string(remote_uuid, uuid);
563 cb_data = __get_rfcomm_cb_data(remote_uuid);
565 return BT_STATUS_FAIL;
567 _bt_convert_addr_type_to_string(remote_addr, addr);
568 DBG("Connecting to %s, uuid %s", remote_addr, remote_uuid);
569 conn = __rfcomm_create_conn_info(remote_addr, sock);
571 __rfcomm_cb_data_remove(cb_data);
572 return BT_STATUS_FAIL;
575 cb_data->conn_info = conn;
576 ret = _bt_discover_services(remote_addr, (char *)remote_uuid,
577 __bt_discover_service_response_cb, cb_data);
578 if (ret != BT_STATUS_SUCCESS) {
579 ERR("Error returned while service discovery");
580 __bt_free_conn(conn);
581 __bt_free_cb_data(cb_data);
582 return BT_STATUS_FAIL;
585 INFO("Adding callback information to rfcomm_clients");
586 rfcomm_clients = g_slist_append(rfcomm_clients, cb_data);
588 return BT_STATUS_SUCCESS;