Пример #1
0
int bt_input(int argc, char *argv[])
{
	GError *error = NULL;
	GOptionContext *context;

	/* Query current locale */
	setlocale(LC_CTYPE, "");

	g_type_init();
	dbus_init();

	context = g_option_context_new("- a bluetooth input manager");
	g_option_context_add_main_entries(context, entries, NULL);
	g_option_context_set_summary(context, "Version "PACKAGE_VERSION);
	g_option_context_set_description(context,
			//"Report bugs to <"PACKAGE_BUGREPORT">."
			"Project home page <"PACKAGE_URL">."
			);

	if (!g_option_context_parse(context, &argc, &argv, &error)) {
		g_print("%s: %s\n", g_get_prgname(), error->message);
		g_print("Try `%s --help` for more information.\n", g_get_prgname());
		exit(EXIT_FAILURE);
	} else if ((!connect_arg || strlen(connect_arg) == 0) && (!disconnect_arg || strlen(disconnect_arg) == 0)) {
		g_print("%s", g_option_context_get_help(context, FALSE, NULL));
		exit(EXIT_FAILURE);
	}

	g_option_context_free(context);

	if (!dbus_system_connect(&error)) {
		g_printerr("Couldn't connect to DBus system bus: %s\n", error->message);
		exit(EXIT_FAILURE);
	}

	/* Check, that bluetooth daemon is running */
	if (!intf_supported(BLUEZ_DBUS_NAME, MANAGER_DBUS_PATH, MANAGER_DBUS_INTERFACE)) {
		g_printerr("%s: bluez service is not found\n", g_get_prgname());
		g_printerr("Did you forget to run bluetoothd?\n");
		exit(EXIT_FAILURE);
	}

	Adapter *adapter = find_adapter(adapter_arg, &error);
	exit_if_error(error);

	Device *device = find_device(adapter, connect_arg != NULL ? connect_arg : disconnect_arg, &error);
	exit_if_error(error);

	if (!intf_supported(BLUEZ_DBUS_NAME, device_get_dbus_object_path(device), INPUT_DBUS_INTERFACE)) {
		g_printerr("Input service is not supported by this device\n");
		exit(EXIT_FAILURE);
	}

	GMainLoop *mainloop = g_main_loop_new(NULL, FALSE);

	Input *input = g_object_new(INPUT_TYPE, "DBusObjectPath", device_get_dbus_object_path(device), NULL);
	g_signal_connect(input, "PropertyChanged", G_CALLBACK(input_property_changed), mainloop);

	if (connect_arg) {
		if (input_get_connected(input) == TRUE) {
			g_print("Input service is already connected\n");
		} else {
			input_connect(input, &error);
			exit_if_error(error);
			g_main_loop_run(mainloop);
		}
	} else if (disconnect_arg) {
		if (input_get_connected(input) == FALSE) {
			g_print("Input service is already disconnected\n");
		} else {
			input_disconnect(input, &error);
			exit_if_error(error);
			g_main_loop_run(mainloop);
		}
	}

	g_main_loop_unref(mainloop);
	g_object_unref(input);
	g_object_unref(device);
	g_object_unref(adapter);
	dbus_disconnect();

	exit(EXIT_SUCCESS);
}
Пример #2
0
static void _bt_agent_method_call_func(GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data)
{
    // g_print("%s%s\n", method_name, g_variant_print(parameters, FALSE));

    if (g_strcmp0(method_name, "AuthorizeService") == 0)
    {
        GError *error = NULL;
        Device *device_obj = device_new(g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL));
        const char *uuid = g_variant_get_string(g_variant_get_child_value(parameters, 1), NULL);

        if (_interactive)
          g_print("Device: %s (%s) for UUID %s\n", device_get_alias(device_obj, &error), device_get_address(device_obj, &error), uuid);

        if (error)
        {
            g_critical("Failed to get remote device's MAC address: %s", error->message);
            g_error_free(error);
            g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "Internal error occurred");
            return;
        }

        if (device_get_paired (device_obj, &error))
        {
            g_dbus_method_invocation_return_value(invocation, NULL);
        }
        else if (error)
        {
            g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "Internal error occurred");
            g_error_free (error);
        }
        else
        {
            g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "Service authorization rejected");
        }
    }
    else if (g_strcmp0(method_name, "Cancel") == 0)
    {
        if (_interactive)
            g_print("Request canceled\n");
        // Return void
        g_dbus_method_invocation_return_value(invocation, NULL);
    }
    else if (g_strcmp0(method_name, "DisplayPasskey") == 0)
    {
        GError *error = NULL;
        Device *device_obj = device_new(g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL));
        const gchar *pin = _find_device_pin(device_get_dbus_object_path(device_obj));

        if (_interactive)
            g_print("Device: %s (%s)\n", device_get_alias(device_obj, &error), device_get_address(device_obj, &error));

        if (error)
        {
            g_critical("Failed to get remote device's MAC address: %s", error->message);
            g_error_free(error);
        }

        g_object_unref(device_obj);

        if (_interactive)
        {
            g_print("Passkey: %u, entered: %u\n", g_variant_get_uint32(g_variant_get_child_value(parameters, 1)), g_variant_get_uint16(g_variant_get_child_value(parameters, 2)));
            g_dbus_method_invocation_return_value(invocation, NULL);
            return;
        }
        else if (pin != NULL)
        {
            /* OK, device found */
            g_dbus_method_invocation_return_value(invocation, NULL);
            return;
        }

        g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "Pairing rejected");
    }
    else if (g_strcmp0(method_name, "DisplayPinCode") == 0)
    {
        GError *error = NULL;
        Device *device_obj = device_new(g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL));
        const gchar *pin = _find_device_pin(device_get_dbus_object_path(device_obj));
        const gchar *pincode = g_variant_get_string(g_variant_get_child_value(parameters, 1), NULL);

        if (_interactive)
            g_print("Device: %s (%s)\n", device_get_alias(device_obj, &error), device_get_address(device_obj, &error));

        if (error)
        {
            g_critical("Failed to get remote device's MAC address: %s", error->message);
            g_error_free(error);
        }

        g_object_unref(device_obj);

        /* Try to use found PIN */
        if (pin != NULL)
        {
            if (g_strcmp0(pin, "*") == 0 || g_strcmp0(pin, pincode) == 0)
            {
                if (_interactive)
                    g_print("Pin code confirmed\n");
                g_dbus_method_invocation_return_value(invocation, NULL);
            }
            else
                g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "Passkey does not match");

            return;
        }
        else if (_interactive)
        {
            g_print("Confirm pin code: %s (yes/no)? ", pincode);

            gchar yn[4] = {0,};
            errno = 0;
            if (scanf("%3s", yn) == EOF && errno)
                g_warning("%s\n", strerror(errno));
            if(g_ascii_strcasecmp(yn, "yes") == 0 || g_ascii_strcasecmp(yn, "y") == 0)
                g_dbus_method_invocation_return_value(invocation, NULL);
            else
                g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "Passkey does not match");
            return;
        }

        g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "Pairing rejected");
    }
    else if (g_strcmp0(method_name, "Release") == 0)
    {
        agent_need_unregister = FALSE;

        if(_mainloop)
            if (g_main_loop_is_running(_mainloop))
                g_main_loop_quit(_mainloop);

        g_print("Agent released\n");

        // Return void
        g_dbus_method_invocation_return_value(invocation, NULL);
    }
    else if (g_strcmp0(method_name, "RequestAuthorization") == 0)
    {
        GError *error = NULL;
        Device *device_obj = device_new(g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL));

        if (_interactive)
            g_print("Device: %s (%s)\n", device_get_alias(device_obj, &error), device_get_address(device_obj, &error));

        if(error)
        {
            g_critical("Failed to get remote device's MAC address: %s", error->message);
            g_error_free(error);
        }

        g_object_unref(device_obj);

        if (_interactive)
        {
            g_print("Authorize this device pairing (yes/no)? ");
            gchar yn[4] = {0,};
            errno = 0;
            if (scanf("%3s", yn) == EOF && errno)
                g_warning("%s\n", strerror(errno));
            if(g_ascii_strcasecmp(yn, "yes") == 0 || g_ascii_strcasecmp(yn, "y") == 0)
                g_dbus_method_invocation_return_value(invocation, NULL);
            else
                g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "Pairing rejected");
            return;
        }

        g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "Pairing rejected");
    }
    else if (g_strcmp0(method_name, "RequestConfirmation") == 0)
    {
        GError *error = NULL;
        Device *device_obj = device_new(g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL));
        guint32 passkey = g_variant_get_uint32(g_variant_get_child_value(parameters, 1));
        const gchar *pin = _find_device_pin(device_get_dbus_object_path(device_obj));

        if (_interactive)
            g_print("Device: %s (%s)\n", device_get_alias(device_obj, &error), device_get_address(device_obj, &error));

        if(error)
        {
            g_critical("Failed to get remote device's MAC address: %s", error->message);
            g_error_free(error);
        }

        g_object_unref(device_obj);

        /* Try to use found PIN */
        if (pin != NULL)
        {
            guint32 passkey_t;
            sscanf(pin, "%u", &passkey_t);

            if (g_strcmp0(pin, "*") == 0 || passkey_t == passkey)
            {
                if (_interactive)
                    g_print("Passkey confirmed\n");
                g_dbus_method_invocation_return_value(invocation, NULL);
            }
            else
                g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "Passkey does not match");

            return;
        }
        else if (_interactive)
        {
            g_print("Confirm passkey: %u (yes/no)? ", passkey);
            gchar yn[4] = {0,};
            errno = 0;
            if (scanf("%3s", yn) == EOF && errno)
                g_warning("%s\n", strerror(errno));
            if(g_ascii_strcasecmp(yn, "yes") == 0 || g_ascii_strcasecmp(yn, "y") == 0)
                g_dbus_method_invocation_return_value(invocation, NULL);
            else
                g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "Passkey does not match");
            return;
        }

        g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "Passkey does not match");
    }
    else if (g_strcmp0(method_name, "RequestPasskey") == 0)
    {
        GError *error = NULL;
        Device *device_obj = device_new(g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL));
        const gchar *pin = _find_device_pin(device_get_dbus_object_path(device_obj));
        guint32 ret = 0;
        gboolean invoke = FALSE;

        if (_interactive)
            g_print("Device: %s (%s)\n", device_get_alias(device_obj, &error), device_get_address(device_obj, &error));

        if(error)
        {
            g_critical("Failed to get remote device's MAC address: %s", error->message);
            g_error_free(error);
        }

        g_object_unref(device_obj);

        /* Try to use found PIN */
        if (pin != NULL)
        {
            if (_interactive)
                g_print("Passkey found\n");
            sscanf(pin, "%u", &ret);
            invoke = TRUE;
        }
        else if (_interactive)
        {
            g_print("Enter passkey: ");
            errno = 0;
            if (scanf("%u", &ret) == EOF && errno)
                g_warning("%s\n", strerror(errno));
            invoke = TRUE;
        }

        if (invoke)
        {
            g_dbus_method_invocation_return_value(invocation, g_variant_new ("(u)", ret));
        }
        else
        {
            g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "No passkey inputted");
        }
    }
    else if (g_strcmp0(method_name, "RequestPinCode") == 0)
    {
        GError *error = NULL;
        Device *device_obj = device_new(g_variant_get_string(g_variant_get_child_value(parameters, 0), NULL));
        const gchar *pin = _find_device_pin(device_get_dbus_object_path(device_obj));
        gchar *ret = NULL;
        gboolean invoke = FALSE;

        if (_interactive)
            g_print("Device: %s (%s)\n", device_get_alias(device_obj, &error), device_get_address(device_obj, &error));

        if(error)
        {
            g_critical("Failed to get remote device's MAC address: %s", error->message);
            g_error_free(error);
        }

        g_object_unref(device_obj);

        /* Try to use found PIN */
        if (pin != NULL)
        {
            if (_interactive)
                g_print("Passkey found\n");
            sscanf(pin, "%ms", &ret);
            invoke = TRUE;
        }
        else if (_interactive)
        {
            g_print("Enter passkey: ");
            errno = 0;
            if (scanf("%ms", &ret) == EOF && errno)
                g_warning("%s\n", strerror(errno));
            invoke = TRUE;
        }

        if (invoke)
        {
            g_dbus_method_invocation_return_value(invocation, g_variant_new ("(s)", ret));
        }
        else
        {
            g_dbus_method_invocation_return_dbus_error(invocation, "org.bluez.Error.Rejected", "No passkey inputted");
        }

        if (ret)
            free(ret);
    }
}