Also, das geht hiermit los: Pair: sdb_bus_bt_call_retry(this->bus, NULL, dev->object, "Pair", NULL, (void*)this); Connect: sdb_bus_bt_call_retry(this->bus, NULL, dev->object, "Pair", NULL, (void*)this); Das ist die dazu gehoerende Methode: void sdb_bus_bt_call_retry(sdb_bus_bt *this, sdb_data *arguments, char *object, char *method, sdb_bus_bt_retry_handler handler, void *argv) { struct sdb_bus_bt_call_data *cdata; cdata = calloc(1, sizeof (struct sdb_bus_bt_call_data)); cdata->this = this; cdata->obj = strdup(object); cdata->tries = 0; cdata->handler = handler; cdata->method = strdup(method); cdata->argv = argv; sdb_bus_call_async((sdb_bus*)this, arguments, "org.bluez", object, "org.bluez.Device1", method, retry_handler, (void*) cdata); } Und die dazu gehoerende: void sdb_bus_call_async(sdb_bus *this, sdb_data *arguments, char *target, char *object, char *interface, char *method, sdb_bus_pending_message_handler_func handler, void *argv) { DBusMessage *message; DBusMessageIter argument_iter; DBusPendingCall *pending; sdb_bus_pending_message_handler *data; printf(RED"Async call"CLR": "MAG"%s"CLR" ("HBLK"%s %s %s"CLR") [%p]\n", method, target, object, interface, argv); // ** init the call message = dbus_message_new_method_call(target, object, interface, method); if (NULL == message) { fprintf(stderr, "Error calling %s on %s: message is NULL\n", method, object); return; } // ** add arguments to the call if (NULL != arguments) { dbus_message_iter_init_append(message, &argument_iter); sdb_data_to_iter(arguments, &argument_iter, 0); } // ** asynchronous call dbus_connection_send_with_reply(this->connection, message, NULL == handler ? NULL : &pending, -1); if (NULL == pending && NULL != handler) { dbus_message_unref(message); fprintf(stderr, "Pending Call Null\n"); return; } if (NULL != handler) { // ** prepare user data for the handler data = calloc(1, sizeof (sdb_bus_pending_message_handler)); data->bus = this; data->handler = handler; data->argv = argv; // ** set handler to the pending call dbus_pending_call_set_notify(pending, sdb_bus_pending_handler, data, NULL); } // ** lets go dbus_connection_flush(this->connection); dbus_message_unref(message); } Durch das dbus_connection_send_with_reply geht alles erst mal in DBus weiter. Wenn DBus einen reply hat callt es data->handler, was in diesem Fall retry_handler ist: static void retry_handler(void *argv, DBusMessage *message) { struct sdb_bus_bt_call_data *cdata = (struct sdb_bus_bt_call_data*) argv; sdb_data *data; int type; bool success = true; type = dbus_message_get_type(message); data = sdb_data_new_from_message(message); if (DBUS_MESSAGE_TYPE_ERROR == type) { if (NULL != data->str_value && 0 == strcmp(data->str_value, "Input/Output error") && cdata->tries++ < 3) { printf("I/O error, trying again\n"); printf("*****\n"); sdb_data_dump(data, 0); printf("-----\n"); usleep(100000); sdb_bus_call_async((sdb_bus*)cdata->this, NULL, "org.bluez", cdata->obj, "org.bluez.Device1", cdata->method, retry_handler, (void*) cdata); goto done; } else success = false; //if(dbus_error_is_set(&cdata->this->base.error)) { // printf("[DBus Error %s] ", cdata->this->base.error.message); // dbus_error_free(&cdata->this->base.error); //} } if (NULL == cdata->handler) { // TODO Notification printf(" * "HGRN"%s""ing"CLR" %s! *:\n", cdata->method, success ? "succeeded" : "failed"); sdb_data_dump(data, 0); } else { cdata->handler(cdata->this, cdata->obj, success, data, cdata->argv); } free(cdata->obj); free(cdata->method); free(cdata); done: sdb_data_destruct(&data, true); } Der versucht den bei bluez manchmal auftretenden i/o Error zu behandeln (drei Versuche). Und wenn der Call erfolgreich war wird der urspruengliche Handler wieder gecallt. In diesem Fall NULL.