Search code examples
ciotkaa

Kaa doesn't send event


I have set up an Kaa server and developed an application with the SDK. but application doesn't send Event massages. this application should send license plate of the cars entered parking to server and also send an event to the another application(receiver app). the application send data to server but doesn't send events.

whats the problem?

this is my code:

static void callback(void *context)
{
    kaa_string_t plate;
    kaa_user_log_record_t *log_record = kaa_logging_data_collection_create();
    plate.data = "some license plate";
    log_record->plate = &plate;
    kaa_logging_add_record(kaa_client_get_context(context)->log_collector, log_record, NULL);
    printf("%s uploaded\n", plate.data);

    kaa_plate_detection_event_plate_event_t *plate_event = kaa_plate_detection_event_plate_event_create();
    plate_event->plate = &plate;
    kaa_error_t error_code = kaa_event_manager_send_kaa_plate_detection_event_plate_event(
            kaa_client_get_context(context)->event_manager, plate_event, NULL);
    //plate_event->destroy(plate_event);
    printf("%s event sent\n", plate.data);
}

Solution

  • Problem Description

    In the beginning of callback() you're defining kaa_string_t plate; ==> It means that its memory is allocated on the stack.

    Later in the same scope, you're creating a pointer to plate_event, and it will be used as argument to the event that you want to send.

    Before you're sending the event, you're assigning plate_event->plate = &plate. It means that plate_event->plate is now pointing to an address on the stack.

    Then, (according to what you wrote in the comments) you're sending the event using an asynchronous function. It means that the thread that is executing this function is not waiting for the message to be really sent - that's the meaning of an asynchronous function. Something else (probably a different thread, depending on the implementation of the send_event function) will take care of the sending. Therefore, it's not guarenteed that the message is sent before the next lines of code are executed.

    In your case it's probable that before the message was sent, the scope of callback() ended. Therefore the memory of this scope is automatically freed and invalid from now, including kaa_string_t plate. Then at some point, the asynchronous sending is executing but it relies on an invalid memory because now plate_event->plate is pointing to a memory that was already freed.

    Possible solution

    Instead of allocating kaa_string_t plate on the stack, allocate it on the heap (malloc). Then the memory is valid until you free it yourself, when you're sure the message was already sent.

    Something like that:

    kaa_string_t *plate = malloc(sizeof(kaa_string_t));
    strncpy(plate, "some license plate", sizeof(kaa_string_t));
    ...
    // Now it's safe to do this:
    plate_event->plate = plate;
    // Sending event code
    ...