我坚持向ARI发送自制模块的stasis_message。
我尝试使用文档中的代码示例:
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");
}
我总是收到如下消息:
对象0x7f2ea5ab8ec5的错误幻数0x332065
此错误附加在方法stasis_create_message()中。
[编辑]
我不理解错误和原因,感谢任何帮助。
正如arheops建议的那样,有创建问题的功能。显然我的对象无法转换为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];
};
我尝试创建像描述here这样的a2对象,我收到错误:
***“星号”中的错误:free():指针无效:
由于
答案 0 :(得分: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);