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); }
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); } }