2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <gio/gunixfdlist.h>
19 #include "bluetooth-api.h"
20 #include "bt-internal-types.h"
22 #include "bt-common.h"
23 #include "bt-request-sender.h"
24 #include "bt-event-handler.h"
26 static int _bluetooth_handle_get_len(const char *str)
29 for (i = 0; str && str[i] != '\0'; i++);
33 BT_EXPORT_API int bluetooth_otp_server_init(const char *directory)
35 int result = BLUETOOTH_ERROR_INTERNAL;
36 bt_user_info_t *user_info;
37 char dir_name[BLUETOOTH_MAX_OTP_SERVER_DIR_NAME];
40 BT_CHECK_ENABLED(return);
42 user_info = _bt_get_user_data(BT_COMMON);
43 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
46 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
49 g_strlcpy(dir_name, directory, sizeof(dir_name));
53 g_array_append_vals(in_param1, dir_name,
54 BLUETOOTH_MAX_OTP_SERVER_DIR_NAME);
56 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_OTP_SERVER_INIT,
57 in_param1, in_param2, in_param3, in_param4,
58 user_info->cb, user_info->user_data);
60 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
66 BT_EXPORT_API int bluetooth_otp_server_deinit()
68 int result = BLUETOOTH_ERROR_INTERNAL;
69 bt_user_info_t *user_info;
72 BT_CHECK_ENABLED(return);
74 user_info = _bt_get_user_data(BT_COMMON);
75 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
78 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
81 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_OTP_SERVER_DEINIT,
82 in_param1, in_param2, in_param3, in_param4,
83 user_info->cb, user_info->user_data);
85 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
91 BT_EXPORT_API int bluetooth_otp_read_characteristic_value(const char *handle)
95 bt_user_info_t *user_info;
96 int result = BLUETOOTH_ERROR_INTERNAL;
99 BT_CHECK_PARAMETER(handle, return);
100 BT_CHECK_ENABLED_LE(return);
102 user_info = _bt_get_user_data(BT_COMMON);
103 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
106 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
108 path = g_strdup(handle);
109 path_len = _bluetooth_handle_get_len(path);
110 g_array_append_vals(in_param1, path, path_len);
113 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_OTP_READ_VALUE,
114 in_param1, in_param2, in_param3, in_param4,
115 user_info->cb, user_info->user_data);
117 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
123 BT_EXPORT_API int bluetooth_otp_enable_notification(const char *handle)
127 bt_user_info_t *user_info;
128 int result = BLUETOOTH_ERROR_INTERNAL;
131 BT_CHECK_PARAMETER(handle, return);
132 BT_CHECK_ENABLED_LE(return);
134 user_info = _bt_get_user_data(BT_COMMON);
135 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
138 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
140 path = g_strdup(handle);
141 path_len = _bluetooth_handle_get_len(path);
142 g_array_append_vals(in_param1, path, path_len);
145 result = _bt_send_request_async(
147 BT_OTP_ENABLE_NOTIFICATION,
148 in_param1, in_param2,
149 in_param3, in_param4,
150 user_info->cb, user_info->user_data);
152 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
158 BT_EXPORT_API int bluetooth_otp_write_characteristics_value(const char *handle,
159 unsigned char *buf, int length)
163 bt_user_info_t *user_info;
164 int result = BLUETOOTH_ERROR_INTERNAL;
165 bluetooth_otp_charc_data_t data;
168 BT_CHECK_PARAMETER(handle, return);
169 BT_CHECK_PARAMETER(buf, return);
170 BT_CHECK_ENABLED_LE(return);
172 user_info = _bt_get_user_data(BT_COMMON);
173 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
176 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
178 memset(&data, 0x00, sizeof(bluetooth_otp_charc_data_t));
180 data.length = length;
182 memcpy(data.data, buf, length);
184 path = g_strdup(handle);
185 path_len = _bluetooth_handle_get_len(path);
188 g_array_append_vals(in_param1, path, path_len);
190 g_array_append_vals(in_param2, &data,
191 sizeof(bluetooth_otp_charc_data_t));
194 for (i = 0; i < length; i++)
195 BT_INFO("Value[%d] = %u", i, buf[i]);
196 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_OTP_WRITE_VALUE,
197 in_param1, in_param2, in_param3, in_param4,
198 user_info->cb, user_info->user_data);
200 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
207 #define BT_OTP_CLIENT_SERVICE_NAME "org.otp.client"
208 #define BT_OTP_CLIENT_OBJECT_PATH "/org/otp/client"
210 static const gchar otc_connection_xml[] =
212 " <interface name='org.otp.otc_channel'>"
213 " <method name='NewConnection'>"
214 " <arg type='o' name='object' direction='in'/>"
215 " <arg type='h' name='fd' direction='in'/>"
220 GDBusNodeInfo *otp_node_info = NULL;
221 static GDBusConnection *g_conn;
222 static guint g_owner_id = 0;
224 static void __new_connection_method(GDBusConnection *connection,
226 const gchar *object_path,
227 const gchar *interface_name,
228 const gchar *method_name,
229 GVariant *parameters,
230 GDBusMethodInvocation *invocation,
233 BT_DBG("method %s", method_name);
234 if (g_strcmp0(method_name, "NewConnection") == 0) {
237 GUnixFDList *fd_list;
239 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
241 bluetooth_otc_info_t *otc_info = NULL;
242 bt_event_info_t *event_info;
243 int result = BLUETOOTH_ERROR_NONE;
245 g_variant_get(parameters, "(oh)", &dev_path, &index);
247 msg = g_dbus_method_invocation_get_message(invocation);
248 fd_list = g_dbus_message_get_unix_fd_list(msg);
249 if (fd_list == NULL) {
250 BT_ERR("fd_list is NULL");
254 fd = g_unix_fd_list_get(fd_list, index, NULL);
256 BT_ERR("Invalid fd return");
260 _bt_convert_device_path_to_address(dev_path, address);
262 BT_INFO("OTC Connected fd: %d, address %s", fd, address);
264 otc_info = g_malloc0(sizeof(bluetooth_otc_info_t));
266 otc_info->connected = TRUE;
267 otc_info->address = g_strdup(address);
269 event_info = _bt_event_get_cb_data(BT_OTP_EVENT);
272 _bt_common_event_cb(BLUETOOTH_EVENT_OTC_STATE_CHANGED,
273 result, otc_info, event_info->cb,
274 event_info->user_data);
277 g_dbus_method_invocation_return_value(invocation, NULL);
281 static const GDBusInterfaceVTable method_table = {
282 __new_connection_method,
287 static void _bt_otp_on_bus_acquired(GDBusConnection *connection,
288 const gchar *name, gpointer user_data)
291 GError *error = NULL;
297 object_id = g_dbus_connection_register_object(connection,
298 BT_OTP_CLIENT_OBJECT_PATH,
299 otp_node_info->interfaces[0],
302 if (object_id == 0) {
303 BT_ERR("Failed to register method table: %s", error->message);
305 g_dbus_node_info_unref(otp_node_info);
311 static void _bt_otp_on_name_acquired(GDBusConnection *connection,
318 static void _bt_otp_on_name_lost(GDBusConnection *connection,
325 g_object_unref(g_conn);
329 g_dbus_node_info_unref(otp_node_info);
333 int _bt_otp_register_interface(void)
336 GError *error = NULL;
339 otp_node_info = g_dbus_node_info_new_for_xml(otc_connection_xml,
341 if (!otp_node_info) {
342 BT_ERR("Failed to install: %s", error->message);
343 return BLUETOOTH_ERROR_INTERNAL;
346 owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
347 BT_OTP_CLIENT_SERVICE_NAME,
348 G_BUS_NAME_OWNER_FLAGS_NONE,
349 _bt_otp_on_bus_acquired,
350 _bt_otp_on_name_acquired,
351 _bt_otp_on_name_lost,
353 g_owner_id = owner_id;
354 BT_DBG("owner_id is [%d]\n", owner_id);
357 return BLUETOOTH_ERROR_NONE;
360 void _bt_otp_unregister_interface(void)
364 g_bus_unown_name(g_owner_id);
369 BT_EXPORT_API int bluetooth_otp_connect_otc(const bluetooth_device_address_t *device_address)
371 int ret = BLUETOOTH_ERROR_INTERNAL;
373 BT_CHECK_PARAMETER(device_address, return);
374 BT_CHECK_ENABLED_LE(return);
377 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
379 g_array_append_vals(in_param1, device_address,
380 sizeof(bluetooth_device_address_t));
382 _bt_otp_register_interface();
384 ret = _bt_send_request(BT_BLUEZ_SERVICE, BT_LE_OTC_CONNECT,
385 in_param1, in_param2, in_param3, in_param4, &out_param);
387 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
392 BT_EXPORT_API int bluetooth_otp_disconnect_otc(const bluetooth_device_address_t *device_address)
394 int ret = BLUETOOTH_ERROR_INTERNAL;
396 BT_CHECK_PARAMETER(device_address, return);
397 BT_CHECK_ENABLED_LE(return);
400 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
401 /* TODO: Send fd as in_param2 */
402 g_array_append_vals(in_param1, device_address,
403 sizeof(bluetooth_device_address_t));
405 ret = _bt_send_request(BT_BLUEZ_SERVICE, BT_LE_OTC_DISCONNECT,
406 in_param1, in_param2, in_param3, in_param4, &out_param);
408 _bt_otp_unregister_interface();
410 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);