Asterisk create_stasis_message Недопустимый магический номер

Я застрял, чтобы отправить stasis_message для самодельного модуля в ARI.

Я пытаюсь использовать пример кода из документации:

https://wiki.asterisk.org/wiki/display/AST/Stasis+Message+Bus

Вместо примера я использую звездочку 13 (кто использует 12), и некоторые подписи изменены.

Вот инициализация:

struct stasis_topic *foo_topic;

static int load_module(void)
{
    //  Register to stasis.
    stasis_app_register(app, callback_stasis, 0);
    // Create a bridge on witch ARI can conenct.
    stasis_app_bridge_create("mixing", app, "11000");

    // Create the topic
    foo_topic = stasis_topic_create(app);
    return ast_register_application_xml(app, exec);
}

И метод кода, который звонит, когда приходит телефон:

static int exec()
{
    publish_foo();
}

static void publish_foo()
{
   printf("Trace 1\n");

   char* test =  "dataToSend";
   RAII_VAR(struct stasis_message_type*, foo_type, NULL, ao2_cleanup);
   stasis_message_type_create(app, NULL, &foo_type);

   RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
   printf("Trace 3\n");
   msg = stasis_message_create(type, test);

   if (!msg)
      return;

    stasis_publish(foo_topic, msg);

    printf("PASSING MESSAGE 4\n");
}

Я всегда получаю сообщение типа:

плохое магическое число 0x332065 для объекта 0x7f2ea5ab8ec5

И эта ошибка добавляется в метод stasis_create_message().

[Редактировать]

Я не понимаю ошибку, поэтому любая помощь приветствуется.

Как предполагают археопы, есть функция, создающая проблему. По-видимому, мой объект не может быть преобразован в объект Asterisk. Вероятно, структура, которую мне нужно отправить в функцию create_message_function, должна иметь тип astobj2.

static struct astobj2 *INTERNAL_OBJ(void *user_data)
{
        struct astobj2 *p;

        if (!user_data) {
                ast_log(LOG_ERROR, "user_data is NULL\n");
                return NULL;
        }

        p = (struct astobj2 *) ((char *) user_data - sizeof(*p));
        if (AO2_MAGIC != p->priv_data.magic) {
                if (p->priv_data.magic) {
                        ast_log(LOG_ERROR, "bad magic number 0x%x for object %p\n",
                                p->priv_data.magic, user_data);
                } else {
                        ast_log(LOG_ERROR,
                                "bad magic number for object %p. Object is likely destroyed.\n",
                                user_data);
                }
                ast_assert(0);
                return NULL;
        }

        return p;
}

И структура определения astobj2:

struct astobj2 
{    
   struct __priv_data priv_data;
   void *user_data[0];
};

Я попытался создать объект a2, как описано здесь, и я получаю сообщение об ошибке:

*** Ошибка в `asterisk': free(): недопустимый указатель:

Спасибо


person Manticore    schedule 07.05.2015    source источник
comment
Могу предложить вам искать исходный код asterisk по плохому магическому номеру   -  person arheops    schedule 07.05.2015


Ответы (1)


Чтобы отправить стазис-сообщение, вам нужно создать объект a2, обычно вы можете выполнить эту часть с помощью макроса:

RAII_VAR

Но я не могу получить рабочий пример с этим, поэтому я создаю сам объект с помощью следующих методов:

typedef struct ast_foo
{
    int n;

} ast_foo;

// Destructor is automatically called when the message is not referenced anymore.
static void foo_dtor(void *obj)
{
    struct foo *obj_foo = obj;
    // Free all resources you have reserve here.
}

/**
 * @return a ast_foo struct, with destructor setted.
 */
static struct ast_foo* make_me_a_foo(void)
{
    struct ast_foo *obj_foo;
    obj_foo = ao2_alloc(sizeof(ast_foo), foo_dtor);

    // if char* do malloc for them.
    if (!obj_foo) {
        ast_log(LOG_NOTICE, "make foo failed... 2\n");
        return NULL;
    }

    return obj_foo;
}

Вот полный пример отправки и подписки стазисного сообщения:

static const char app[] = "StasisTest";
struct stasis_topic *foo_topic;

typedef struct ast_foo
{
    int n;

} ast_foo;

// Destructor automatically call when message is not referenced anymore.
static void foo_dtor(void *obj)
{
    struct foo *obj_foo = obj;
    // Free all resources you have reserve here.
}

/**
 * @return a ast_foo struct, with destructor setted.
 */
static struct ast_foo* make_me_a_foo(void)
{
    struct ast_foo *obj_foo;
    obj_foo = ao2_alloc(sizeof(ast_foo), foo_dtor);

    // if char* do malloc for them.
    if (!obj_foo) {
        ast_log(LOG_NOTICE, "make foo failed... 2\n");
        return NULL;
    }

    return obj_foo;
}

/**
 * Send a stasis message, with the long way...
 */
static void publish_foo()
{
    ast_log(LOG_NOTICE, "Enter publish message\n");
    RAII_VAR(struct stasis_message_type*, foo_type, NULL, ao2_cleanup);

    ast_log(LOG_NOTICE, "Create data to send\n");
    ast_foo* foo_data = make_me_a_foo();
    foo_data->n = 12;

    ast_log(LOG_NOTICE, "Create the message to send.\n");
    stasis_message_type_create(app, NULL, &foo_type);

    if (!foo_type)
    {
        ast_log(LOG_NOTICE, "Oh no my type is NULL \n");
    }
    else
    {
        ast_log(LOG_NOTICE, "Ok foo type \n");
    }

    RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
    msg = stasis_message_create(foo_type, foo_data);

    if (!msg)
    {
        ast_log(LOG_NOTICE, "Fail to send message\n");
        sleep(1);
        return;
    }

    stasis_publish(foo_topic, msg);
}

static int exec()
{
    // First method.
    publish_foo();

    return 0;
}

static int unload_module(void) {
    stasis_app_unregister(app);

    ao2_cleanup(foo_topic);
    foo_topic = NULL;
    return ast_unregister_application(app);
}


void bar_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message)
{
    ast_log(LOG_NOTICE, "Test stasis received a message from topic\n");
}

static int load_module(void) {
    stasis_init();

    // Register.
    ast_foo* foo_data2 = make_me_a_foo();
    foo_topic = stasis_topic_create("StasisTest");
    stasis_subscribe(foo_topic, bar_callback, foo_data2);

    return ast_register_application_xml(app, exec);
}

Но есть действительно более простой способ с отправкой json-объекта.

#include "asterisk.h"

ASTERISK_FILE_VERSION(__FILE__, "$Revision$")

#include "asterisk/astobj2.h"
#include "asterisk/module.h"
#include "asterisk/stasis.h"
#include "asterisk/json.h"
#include "asterisk/stasis_app.h"

#include "StasisTest.h"

#define AST_MODULE "stasis_test"

static const char app[] = "StasisTest";

static int exec()
{
    // Second simpler method.
    struct ast_json* inte = ast_json_integer_create(51);
    int result = stasis_app_send("StasisTest", inte);
    ast_log(LOG_NOTICE, "Stasis send %d\n", result);

    return 0;
}

static int unload_module(void) 
{
    stasis_app_unregister(app);
    return ast_unregister_application(app);
}

//Test stasis
void callback_stasis(void* data, const char* app_name, struct ast_json* message)
{
    ast_log(LOG_NOTICE, "Receive a stasis message from json\n");

    int json_res = ast_json_integer_get(message);
    ast_log(LOG_NOTICE, "Integer get : %d\n", json_res);
}

static int load_module(void) {
    stasis_init();
    // Register for the short way.
    stasis_app_register(app, callback_stasis, 0);

    return ast_register_application_xml(app, exec);
}

AST_MODULE_INFO(ASTERISK_GPL_KEY, 0, "The wonders of foo", .load = load_module, .unload = unload_module);
person Manticore    schedule 11.05.2015