lbm.txt.c
02.07.2020 13:31:19
0 MB (8606d6e49fba80652fb39707d8bd7f5b)
http://files.q3t.de/a/get/b54e8ad3eb8eb37077690eeda5eb5220
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.