weliem / bluez_inc

A C library for Bluez (BLE) that hides all DBus communication. It doesn't get easier than this. This library can also be used in C++.
MIT License
84 stars 19 forks source link

Does the peripheral case call binc_advertisement_set_service_data not work properly? failed to register advertisement (error 36: GDBus.Error:org.bluez.Error.Failed: Failed to parse advertisement.) #54

Closed chcmq closed 2 weeks ago

chcmq commented 2 weeks ago
int main(void) {
    // Get a DBus connection
    GDBusConnection *dbusConnection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);

    // Setup handler for CTRL+C
    if (signal(SIGINT, cleanup_handler) == SIG_ERR)
        log_error(TAG, "can't catch SIGINT");

    // Setup mainloop
    loop = g_main_loop_new(NULL, FALSE);

    // Get the default default_adapter
    default_adapter = binc_adapter_get_default(dbusConnection);

    if (default_adapter != NULL) {
        log_debug(TAG, "using default_adapter '%s'", binc_adapter_get_path(default_adapter));

        // Make sure the adapter is on
        binc_adapter_set_powered_state_cb(default_adapter, &on_powered_state_changed);
        if (!binc_adapter_get_powered_state(default_adapter)) {
            binc_adapter_power_on(default_adapter);
        }

        // Setup remote central connection state callback
        binc_adapter_set_remote_central_cb(default_adapter, &on_central_state_changed);

        // Setup advertisement
        GPtrArray *adv_service_uuids = g_ptr_array_new();
        g_ptr_array_add(adv_service_uuids, HTS_SERVICE_UUID);

        advertisement = binc_advertisement_create();
        binc_advertisement_set_local_name(advertisement, "BINC");
        binc_advertisement_set_interval(advertisement, 500, 500);
        binc_advertisement_set_services(advertisement, adv_service_uuids);
        const char *service_uuids = "63fb65cc-c38c-40ed-beeb-071f0b76e10e";
        GByteArray *byte = g_byte_array_new();
        g_byte_array_append(byte, (const guint8 *)"\x01\x02\x03\x04", 4);
        binc_advertisement_set_service_data(advertisement, service_uuids, byte);
        g_byte_array_unref(byte);
        g_ptr_array_free(adv_service_uuids, TRUE);
        binc_adapter_start_advertising(default_adapter, advertisement);

        // Start application
        app = binc_create_application(default_adapter);
        binc_application_add_service(app, HTS_SERVICE_UUID);
        binc_application_add_characteristic(
                app,
                HTS_SERVICE_UUID,
                TEMPERATURE_CHAR_UUID,
                GATT_CHR_PROP_INDICATE);
        binc_application_add_descriptor(
                app,
                HTS_SERVICE_UUID,
                TEMPERATURE_CHAR_UUID,
                CUD_CHAR,
                GATT_CHR_PROP_READ | GATT_CHR_PROP_WRITE);

        const guint8 cud[] = "hello there";
        GByteArray *cudArray = g_byte_array_sized_new(sizeof(cud));
        g_byte_array_append(cudArray, cud, sizeof(cud));
        binc_application_set_desc_value(app, HTS_SERVICE_UUID, TEMPERATURE_CHAR_UUID, CUD_CHAR, cudArray);

        binc_application_set_char_read_cb(app, &on_local_char_read);
        binc_application_set_char_write_cb(app, &on_local_char_write);
        binc_application_set_char_start_notify_cb(app, &on_local_char_start_notify);
        binc_application_set_char_stop_notify_cb(app, &on_local_char_stop_notify);
        binc_adapter_register_application(default_adapter, app);
    } else {
        log_debug("MAIN", "No default_adapter found");
    }

    // Bail out after some time
    g_timeout_add_seconds(600, callback, loop);

    // Start the mainloop
    g_main_loop_run(loop);

    // Clean up mainloop
    g_main_loop_unref(loop);

    // Disconnect from DBus
    g_dbus_connection_close_sync(dbusConnection, NULL, NULL);
    g_object_unref(dbusConnection);
    return 0;
}

2024-08-29 20:01:31:853 DEBUG [Adapter] finding adapters
2024-08-29 20:01:31:857 DEBUG [Adapter] found 1 adapter
2024-08-29 20:01:31:858 DEBUG [Application] successfully published application
2024-08-29 20:01:31:859 DEBUG [Application] successfully published local service 63fb65cc-c38c-40ed-beeb-071f0b76e10e
2024-08-29 20:01:31:859 DEBUG [Application] successfully published local characteristic 1364bc13-dcc4-4f97-8d1f-59be4de2621a
2024-08-29 20:01:31:859 DEBUG [DEBUG] on binc_application_set_char_read_cb
2024-08-29 20:01:31:860 DEBUG [DEBUG] on binc_application_set_char_write_cb
2024-08-29 20:01:31:860 DEBUG [DEBUG] on binc_application_set_char_start_notify_cb
2024-08-29 20:01:31:860 DEBUG [Main] using default_adapter '/org/bluez/hci0'
2024-08-29 20:01:31:866 DEBUG [Application] adding /org/bluez/bincapplication/service0
2024-08-29 20:01:31:867 DEBUG [Application] adding /org/bluez/bincapplication/service0/char0
2024-08-29 20:01:31:878 DEBUG [Adapter] successfully registered application
2024-08-29 20:01:31:878 DEBUG [Adapter] failed to register advertisement (error 36: GDBus.Error:org.bluez.Error.Failed: Failed to parse advertisement.)
weliem commented 2 weeks ago

Tried your code and it working fine on my machine. No issues.

But I think you changed HTS_SERVICE_UUID to be "63fb65cc-c38c-40ed-beeb-071f0b76e10e". If I try that I get the same error. Pretty sure it is because the Advertisement is getting too large. If I comment out the line where you add the HTS_SERVICE_UUID to the advertisement, then it works again....

chcmq commented 2 weeks ago

May I ask what kind of code you run normally? Can you provide it?

How to modify the following cases


const char *service_uuids = "63fb65cc-c38c-40ed-beeb-071f0b76e10e";
        GByteArray *byte = g_byte_array_new();
        g_byte_array_append(byte, (const guint8 *)"\x01\x02\x03\x04", 4);
        binc_advertisement_set_service_data(advertisement, service_uuids, byte);
        g_byte_array_unref(byte);
chcmq commented 2 weeks ago

Now the AD parameters set are too few, I need to add some custom parameters, so I need to use "binc_advertisement_set_service_data" to set the data of "service_data"