Я использую библиотеку gattlib C, чтобы общаться с устройством Bluetooth и установить обработчик уведомлений для UUID, который работает нормально, но когда я также вызываю команду отправки DBus из обработчика (используя libdbus), это не работает -ничего не проходит (я проверяю, что не проходит, читая интерфейс другого процесса).
Я пробовал и функцию получения, и функцию отправки, и они работают изолированно без моего кода, например: я могуотправлять сообщения и видеть их получение, используя два процесса, если я использую только пример кода здесь: http://www.matthew.ath.cx/misc/dbus
Ниже мой код;
#define DBUS_API_SUBJECT_TO_CHANGE
#include <assert.h>
#include <glib.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <systemd/sd-daemon.h>
#include <dbus/dbus.h>
#include "gattlib.h"
// Heart Rate UUID
const uuid_t g_heart_rate_uuid = CREATE_UUID16(0x2A37);
static GMainLoop *m_main_loop;
FILE *fp;
void sendsignal(char* sigvalue)
{
DBusMessage* msg;
DBusMessageIter args;
DBusConnection* conn;
DBusError err;
int ret;
dbus_uint32_t serial = 0;
printf("Sending signal with value %s\n", sigvalue);
// initialise the error value
dbus_error_init(&err);
// connect to the DBUS system bus, and check for errors
conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
if (dbus_error_is_set(&err)) {
fprintf(stderr, "Connection Error (%s)\n", err.message);
dbus_error_free(&err);
}
if (NULL == conn) {
exit(1);
}
// register our name on the bus, and check for errors
ret = dbus_bus_request_name(conn, "test.signal.source", DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
if (dbus_error_is_set(&err)) {
fprintf(stderr, "Name Error (%s)\n", err.message);
dbus_error_free(&err);
}
if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
exit(1);
}
// create a signal & check for errors
msg = dbus_message_new_signal("/test/signal/Object", // object name of the signal
"test.signal.Type", // interface name of the signal
"Test"); // name of the signal
if (NULL == msg)
{
fprintf(stderr, "Message Null\n");
exit(1);
}
// append arguments onto signal
dbus_message_iter_init_append(msg, &args);
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &sigvalue)) {
fprintf(stderr, "Out Of Memory!\n");
exit(1);
}
// send the message and flush the connection
if (!dbus_connection_send(conn, msg, &serial)) {
fprintf(stderr, "Out Of Memory!\n");
exit(1);
}
//dbus_connection_flush(conn);
printf("Signal Sent\n");
// free the message and close the connection
dbus_message_unref(msg);
dbus_connection_close(conn);
}
void notification_handler(
const uuid_t* uuid,
const uint8_t* data,
size_t data_length,
void* user_data){
int rrInterval_one, rrInterval_two;
char str[10];
for (int i=0; i<9; i++){
str[i] = '\0';
}
fp = fopen("/home/research/Desktop/bluetooth/gattlib/build-dir/heart_rate_and_rr.txt", "w");
if (fp == NULL)
{
printf("Error opening file!\n");
exit(1);
}
if (data_length == 2){
printf("HR: %d", data[1]);
fprintf (fp, "HR: %d", data[1]);
sprintf(str, "%d", data[1]);
sendsignal(str);
sd_notify(0,"WATCHDOG=1");
}
else if (data_length == 4)
{
printf("HR: %d", data[1]);
fprintf (fp, "HR: %d", data[1]);
sprintf(str, "%d", data[1]);
rrInterval_one = (data[3]* 0x100) + (data[2]);
fprintf (fp, " RR-Interval: %d", rrInterval_one);
printf (" RR-Interval: %d \n", rrInterval_one);
sendsignal(str);
sd_notify(0,"WATCHDOG=1");
}
else if (data_length == 6)
{
printf("HR: %d", data[1]);
fprintf (fp, "HR: %d", data[1]);
sprintf(str, "%d", data[1]);
rrInterval_one =(data[3]* 0x100) + (data[2]);
rrInterval_two =(data[5]* 0x100) + (data[4]);
fprintf (fp, " RR-Interval: %d %d", rrInterval_one, rrInterval_two);
printf (" RR-Interval: %d", rrInterval_one);
printf (" %d\n", rrInterval_two);
sendsignal(str);
sd_notify(0,"WATCHDOG=1");
}
fclose(fp);
}
static void on_user_abort(int arg) {
g_main_loop_quit(m_main_loop);
}
static void usage(char *argv[]) {
printf("%s <device_address>\n", argv[0]);
}
int main(int argc, char *argv[]) {
int ret;
gatt_connection_t* connection;
if (argc != 2) {
usage(argv);
return 1;
}
connection = gattlib_connect(NULL, argv[1], GATTLIB_CONNECTION_OPTIONS_LEGACY_DEFAULT);
if (connection == NULL) {
fprintf(stderr, "Fail to connect to the bluetooth device.\n");
return 1;
}
gattlib_register_notification(connection, notification_handler, NULL);
ret = gattlib_notification_start(connection, &g_heart_rate_uuid);
if (ret) {
fprintf(stderr, "Fail to start notification\n.");
goto DISCONNECT;
}
// Catch CTRL-C
signal(SIGINT, on_user_abort);
// Start-up notification to the service manager
sd_notify(0, "READY=1");
fprintf(stderr, "Connected to Bluetooth Device\n");
m_main_loop = g_main_loop_new(NULL, 0);
g_main_loop_run(m_main_loop);
// In case we quit the main loop, clean the connection
gattlib_notification_stop(connection, &g_heart_rate_uuid);
g_main_loop_unref(m_main_loop);
DISCONNECT:
gattlib_disconnect(connection);
puts("Done");
return ret;
}
Это не дает мне никакой ошибкисообщения, но на второй итерации обработчика код выходит из кода ниже, если я не закомментирую проверку для DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER и когда я это сделаю, код выполняется, но все же я ничего не вижу со стороны получения.
if (dbus_error_is_set(&err)) {
fprintf(stderr, "Name Error (%s)\n", err.message);
dbus_error_free(&err);
}
if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
exit(1);
}
Я действительно подозреваю, что проблема в главном цикле событий, потому что даже когда я перемещаю DBUS, отправьте функциюна (или только на той его части, которая создает соединение с шиной) внутри Main () - я все еще не вижу имя шины, однако, используя d-футы, когда я проверяю - я знаю, что ей присваивается уникальное имя (например,: 1.113), который тоже не виден с d-футами (я пытаюсь использовать SESSION Bus, если кто-то задается вопросом).