* limitations under the License.
*
*/
+#include <gio/gunixfdlist.h>
#include "bluetooth-api.h"
#include "bt-internal-types.h"
#include "bt-request-sender.h"
#include "bt-event-handler.h"
+static int _bluetooth_handle_get_len(const char *str)
+{
+ int i;
+ for (i = 0; str && str[i] != '\0'; i++);
+ return i;
+}
+
BT_EXPORT_API int bluetooth_otp_server_init(const char *directory)
{
int result = BLUETOOTH_ERROR_INTERNAL;
else
dir_name[0] = '\0';
- g_array_append_vals(in_param1, dir_name, BLUETOOTH_MAX_OTP_SERVER_DIR_NAME);
+ g_array_append_vals(in_param1, dir_name,
+ BLUETOOTH_MAX_OTP_SERVER_DIR_NAME);
result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_OTP_SERVER_INIT,
in_param1, in_param2, in_param3, in_param4,
BT_DBG("-");
return result;
-}
\ No newline at end of file
+}
+
+BT_EXPORT_API int bluetooth_otp_read_characteristic_value(const char *handle)
+{
+ char *path;
+ int path_len = 0;
+ bt_user_info_t *user_info;
+ int result = BLUETOOTH_ERROR_INTERNAL;
+ BT_DBG("+");
+
+ BT_CHECK_PARAMETER(handle, return);
+ BT_CHECK_ENABLED_LE(return);
+
+ user_info = _bt_get_user_data(BT_COMMON);
+ retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ BT_INIT_PARAMS();
+ BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ path = g_strdup(handle);
+ path_len = _bluetooth_handle_get_len(path);
+ g_array_append_vals(in_param1, path, path_len);
+ g_free(path);
+
+ result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_OTP_READ_VALUE,
+ in_param1, in_param2, in_param3, in_param4,
+ user_info->cb, user_info->user_data);
+
+ BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ BT_DBG("-");
+ return result;
+}
+
+BT_EXPORT_API int bluetooth_otp_enable_notification(const char *handle)
+{
+ char *path;
+ int path_len = 0;
+ bt_user_info_t *user_info;
+ int result = BLUETOOTH_ERROR_INTERNAL;
+ BT_DBG("+");
+
+ BT_CHECK_PARAMETER(handle, return);
+ BT_CHECK_ENABLED_LE(return);
+
+ user_info = _bt_get_user_data(BT_COMMON);
+ retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ BT_INIT_PARAMS();
+ BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ path = g_strdup(handle);
+ path_len = _bluetooth_handle_get_len(path);
+ g_array_append_vals(in_param1, path, path_len);
+ g_free(path);
+
+ result = _bt_send_request_async(
+ BT_BLUEZ_SERVICE,
+ BT_OTP_ENABLE_NOTIFICATION,
+ in_param1, in_param2,
+ in_param3, in_param4,
+ user_info->cb, user_info->user_data);
+
+ BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ BT_DBG("-");
+ return result;
+}
+
+BT_EXPORT_API int bluetooth_otp_write_characteristics_value(const char *handle,
+ unsigned char *buf, int length)
+{
+ char *path;
+ int path_len = 0;
+ bt_user_info_t *user_info;
+ int result = BLUETOOTH_ERROR_INTERNAL;
+ bluetooth_otp_charc_data_t data;
+ BT_DBG("+");
+
+ BT_CHECK_PARAMETER(handle, return);
+ BT_CHECK_PARAMETER(buf, return);
+ BT_CHECK_ENABLED_LE(return);
+
+ user_info = _bt_get_user_data(BT_COMMON);
+ retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+ BT_INIT_PARAMS();
+ BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ memset(&data, 0x00, sizeof(bluetooth_otp_charc_data_t));
+
+ data.length = length;
+ if (length > 0)
+ memcpy(data.data, buf, length);
+
+ path = g_strdup(handle);
+ path_len = _bluetooth_handle_get_len(path);
+
+ /*Fill parameters*/
+ g_array_append_vals(in_param1, path, path_len);
+
+ g_array_append_vals(in_param2, &data,
+ sizeof(bluetooth_otp_charc_data_t));
+
+ int i;
+ for (i = 0; i < length; i++)
+ BT_INFO("Value[%d] = %u", i, buf[i]);
+ result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_OTP_WRITE_VALUE,
+ in_param1, in_param2, in_param3, in_param4,
+ user_info->cb, user_info->user_data);
+
+ BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ g_free(path);
+ BT_DBG("-");
+ return result;
+}
+
+#define BT_OTP_CLIENT_SERVICE_NAME "org.otp.client"
+#define BT_OTP_CLIENT_OBJECT_PATH "/org/otp/client"
+
+static const gchar otc_connection_xml[] =
+"<node name='/'>"
+" <interface name='org.otp.otc_channel'>"
+" <method name='NewConnection'>"
+" <arg type='o' name='object' direction='in'/>"
+" <arg type='h' name='fd' direction='in'/>"
+" </method>"
+" </interface>"
+"</node>";
+
+GDBusNodeInfo *otp_node_info = NULL;
+static GDBusConnection *g_conn;
+static guint g_owner_id = 0;
+
+static void __new_connection_method(GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ BT_DBG("method %s", method_name);
+ if (g_strcmp0(method_name, "NewConnection") == 0) {
+ int index;
+ GDBusMessage *msg;
+ GUnixFDList *fd_list;
+ char *dev_path;
+ char address[BT_ADDRESS_STRING_SIZE] = { 0 };
+ int fd;
+ bluetooth_otc_info_t *otc_info = NULL;
+ bt_event_info_t *event_info;
+ int result = BLUETOOTH_ERROR_NONE;
+
+ g_variant_get(parameters, "(oh)", &dev_path, &index);
+
+ msg = g_dbus_method_invocation_get_message(invocation);
+ fd_list = g_dbus_message_get_unix_fd_list(msg);
+ if (fd_list == NULL) {
+ BT_ERR("fd_list is NULL");
+ return;
+ }
+
+ fd = g_unix_fd_list_get(fd_list, index, NULL);
+ if (fd == -1) {
+ BT_ERR("Invalid fd return");
+ return;
+ }
+
+ _bt_convert_device_path_to_address(dev_path, address);
+
+ BT_INFO("OTC Connected fd: %d, address %s", fd, address);
+
+ otc_info = g_malloc0(sizeof(bluetooth_otc_info_t));
+ otc_info->fd = fd;
+ otc_info->connected = TRUE;
+ otc_info->address = g_strdup(address);
+
+ event_info = _bt_event_get_cb_data(BT_OTP_EVENT);
+
+ if (event_info) {
+ _bt_common_event_cb(BLUETOOTH_EVENT_OTC_STATE_CHANGED,
+ result, otc_info, event_info->cb,
+ event_info->user_data);
+ }
+
+ g_free(otc_info->address);
+ g_free(otc_info);
+
+ g_dbus_method_invocation_return_value(invocation, NULL);
+ }
+}
+
+static const GDBusInterfaceVTable method_table = {
+ __new_connection_method,
+ NULL,
+ NULL,
+};
+
+static void _bt_otp_on_bus_acquired(GDBusConnection *connection,
+ const gchar *name, gpointer user_data)
+{
+ guint object_id;
+ GError *error = NULL;
+
+ BT_DBG("+");
+
+ g_conn = connection;
+
+ object_id = g_dbus_connection_register_object(connection,
+ BT_OTP_CLIENT_OBJECT_PATH,
+ otp_node_info->interfaces[0],
+ &method_table,
+ NULL, NULL, &error);
+ if (object_id == 0) {
+ BT_ERR("Failed to register method table: %s", error->message);
+ g_error_free(error);
+ g_dbus_node_info_unref(otp_node_info);
+ }
+
+ BT_DBG("-");
+}
+
+static void _bt_otp_on_name_acquired(GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ BT_DBG("");
+}
+
+static void _bt_otp_on_name_lost(GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ BT_DBG("+");
+
+ if (g_conn) {
+ g_object_unref(g_conn);
+ g_conn = NULL;
+ }
+
+ g_dbus_node_info_unref(otp_node_info);
+ BT_DBG("-");
+}
+
+int _bt_otp_register_interface(void)
+{
+ BT_DBG("+");
+ GError *error = NULL;
+ guint owner_id;
+
+ otp_node_info = g_dbus_node_info_new_for_xml(otc_connection_xml,
+ &error);
+ if (!otp_node_info) {
+ BT_ERR("Failed to install: %s", error->message);
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
+ BT_OTP_CLIENT_SERVICE_NAME,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ _bt_otp_on_bus_acquired,
+ _bt_otp_on_name_acquired,
+ _bt_otp_on_name_lost,
+ NULL, NULL);
+ g_owner_id = owner_id;
+ BT_DBG("owner_id is [%d]\n", owner_id);
+
+ BT_DBG("-");
+ return BLUETOOTH_ERROR_NONE;
+}
+
+void _bt_otp_unregister_interface(void)
+{
+ BT_DBG("+");
+
+ g_bus_unown_name(g_owner_id);
+
+ BT_DBG("-");
+}
+
+BT_EXPORT_API int bluetooth_otp_connect_otc(const bluetooth_device_address_t *device_address)
+{
+ int ret = BLUETOOTH_ERROR_INTERNAL;
+
+ BT_CHECK_PARAMETER(device_address, return);
+ BT_CHECK_ENABLED_LE(return);
+
+ BT_INIT_PARAMS();
+ BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ g_array_append_vals(in_param1, device_address,
+ sizeof(bluetooth_device_address_t));
+
+ _bt_otp_register_interface();
+
+ ret = _bt_send_request(BT_BLUEZ_SERVICE, BT_LE_OTC_CONNECT,
+ in_param1, in_param2, in_param3, in_param4, &out_param);
+
+ BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ return ret;
+}
+
+BT_EXPORT_API int bluetooth_otp_disconnect_otc(const bluetooth_device_address_t *device_address)
+{
+ int ret = BLUETOOTH_ERROR_INTERNAL;
+
+ BT_CHECK_PARAMETER(device_address, return);
+ BT_CHECK_ENABLED_LE(return);
+
+ BT_INIT_PARAMS();
+ BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+ /* TODO: Send fd as in_param2 */
+ g_array_append_vals(in_param1, device_address,
+ sizeof(bluetooth_device_address_t));
+
+ ret = _bt_send_request(BT_BLUEZ_SERVICE, BT_LE_OTC_DISCONNECT,
+ in_param1, in_param2, in_param3, in_param4, &out_param);
+
+ _bt_otp_unregister_interface();
+
+ BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ return ret;
+}