30 #include "transaction.h"
31 #include "transport.h"
33 #define AEAP_RECV_SIZE 32768
45 #define USER_DATA_BUCKETS 11
60 static int tsx_end(
void *obj,
void *arg,
int flags)
62 aeap_transaction_end(obj, -1);
67 static void aeap_destructor(
void *obj)
93 aeap = ao2_alloc(
sizeof(*aeap), aeap_destructor);
95 ast_log(LOG_ERROR,
"AEAP: unable to create");
103 aeap_user_data_hash_fn, NULL, aeap_user_data_cmp_fn);
105 aeap_error(aeap, NULL,
"unable to create user data container");
112 aeap_error(aeap, NULL,
"unable to create transactions container");
117 aeap->
transport = aeap_transport_create(transport_type);
119 aeap_error(aeap, NULL,
"unable to create transport");
132 ast_assert(
id != NULL);
144 strcpy(data->
id,
id);
155 data = aeap_user_data_create(
id, obj, cleanup);
204 aeap_error(aeap, NULL,
"%s", error_msg);
211 for (i = 0; i < size; ++i) {
212 if (ast_strlen_zero(handlers[i].name)) {
225 return on_message(aeap, msg, data);
231 "Unsupported and/or un-handled message"));
236 static void raise_msg(
struct ast_aeap *aeap,
const void *buf, intmax_t size,
253 aeap_transaction_cancel_timer(tsx);
257 msg, tsx ? aeap_transaction_user_obj(tsx) : NULL);
260 msg, tsx ? aeap_transaction_user_obj(tsx) : NULL);
264 aeap_transaction_end(tsx, res);
269 static void *aeap_receive(
void *data)
276 aeap_error(aeap, NULL,
"unable to create read buffer");
277 goto aeap_receive_error;
280 while (aeap_transport_is_connected(aeap->
transport)) {
284 size = aeap_transport_read(aeap->
transport, buf, AEAP_RECV_SIZE, &rtype);
286 goto aeap_receive_error;
294 case AST_AEAP_DATA_TYPE_BINARY:
299 case AST_AEAP_DATA_TYPE_STRING:
300 ast_debug(3,
"AEAP: received message: %s\n", (
char *)buf);
309 raise_msg(aeap, buf, size, rtype);
321 aeap_error(aeap, NULL,
"unrecoverable read error, disconnecting");
342 if (aeap_transport_is_connected(aeap->
transport)) {
347 if (aeap_transport_connect(aeap->
transport, url, protocol, timeout)) {
348 aeap_error(aeap, NULL,
"unable to connect transport");
353 aeap_receive, aeap)) {
354 aeap_error(aeap, NULL,
"unable to start read thread: %s",
385 aeap_transport_disconnect(aeap->
transport);
404 static int aeap_send(
struct ast_aeap *aeap,
const void *buf, uintmax_t size,
409 num = aeap_transport_write(aeap->
transport, buf, size, type);
417 aeap_error(aeap, NULL,
"error sending data");
422 aeap_error(aeap, NULL,
"not all data sent");
427 aeap_error(aeap, NULL,
"sent data truncated");
436 return aeap_send(aeap, buf, size, AST_AEAP_DATA_TYPE_BINARY);
446 aeap_error(aeap, NULL,
"no message to send");
451 aeap_error(aeap, NULL,
"unable to serialize outgoing message");
474 aeap_transaction_params_cleanup(params);
475 aeap_error(aeap, NULL,
"no message to send");
480 tsx = aeap_transaction_create_and_add(aeap->
transactions,
487 aeap_transaction_end(tsx, -1);
491 if (aeap_transaction_start(tsx)) {
492 aeap_transaction_end(tsx, -1);
496 res = aeap_transaction_result(tsx);
enum AST_AEAP_DATA_TYPE ast_aeap_message_serial_type(const struct ast_aeap_message_type *type)
Retrieve the serial type a message type.
Asterisk External Application Protocol API.
void(* on_binary)(struct ast_aeap *aeap, const void *buf, intmax_t size)
Raised when binary data is received.
Callbacks and other parameters used by an Asterisk external application object.
void ast_aeap_user_data_unregister(struct ast_aeap *aeap, const char *id)
Un-register a user data object.
Asterisk main include file. File version handling, generic pbx functions.
AO2_STRING_FIELD_HASH_FN(transport_monitor, key)
Hashing function for struct transport_monitor.
void(* on_string)(struct ast_aeap *aeap, const char *buf, intmax_t size)
Raised when string data is received.
String manipulation functions.
Asterisk External Application Protocol Message API.
The arg parameter is a search key, but is not an object.
struct ao2_container * transactions
const struct ast_aeap_message_handler * request_handlers
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
int ast_aeap_message_is_named(const struct ast_aeap_message *message, const char *name)
Check whether or not a message's name matches the given one.
void(* ast_aeap_user_obj_cleanup)(void *obj)
Callback to cleanup a user object.
struct aeap_transport * transport
int(* ast_aeap_on_message)(struct ast_aeap *aeap, struct ast_aeap_message *message, void *obj)
Event raised when a message is received.
AO2_STRING_FIELD_CMP_FN(transport_monitor, key)
Comparison function for struct transport_monitor.
uintmax_t request_handlers_size
const struct ast_aeap_message_type * msg_type
#define ao2_t_alloc_options(data_size, destructor_fn, options, debug_msg)
Allocate and initialize an object.
int ast_aeap_send_msg_tsx(struct ast_aeap *aeap, struct ast_aeap_tsx_params *params)
Send a transaction based message to an external application using the given parameters.
void * ast_aeap_user_data_object_by_id(struct ast_aeap *aeap, const char *id)
Retrieve a registered user data object by its id.
Parameters to be used when sending a transaction based message.
struct ast_aeap * ast_aeap_create(const char *type, const struct ast_aeap_params *params)
Create an Asterisk external application object.
struct ao2_container * user_data
const char * ast_aeap_message_id(const struct ast_aeap_message *message)
Retrieve a message id.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
static void cleanup(void)
Clean up any old apps that we don't need any more.
int ast_aeap_send_msg(struct ast_aeap *aeap, struct ast_aeap_message *msg)
Send a message to an external application.
int ast_aeap_connect(struct ast_aeap *aeap, const char *url, const char *protocol, int timeout)
Connect to an external application.
int ast_aeap_disconnect(struct ast_aeap *aeap)
Disconnect an Asterisk external application object.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ast_debug(level,...)
Log a DEBUG message.
const char * ast_aeap_message_name(const struct ast_aeap_message *message)
Retrieve a message name.
int ast_aeap_message_is_request(const struct ast_aeap_message *message)
Retrieve whether or not this is a request message.
const struct ast_aeap_params * params
struct ast_aeap * ast_aeap_create_and_connect(const char *type, const struct ast_aeap_params *params, const char *url, const char *protocol, int timeout)
Create and connect to an Asterisk external application.
int ast_aeap_message_serialize(const struct ast_aeap_message *message, void **buf, intmax_t *size)
Serialize the given message object into a byte/char buffer.
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
int ast_aeap_user_data_register(struct ast_aeap *aeap, const char *id, void *obj, ast_aeap_user_obj_cleanup cleanup)
Register a user data object.
void(* on_error)(struct ast_aeap *aeap)
Raised when an error occurs during reading.
struct ast_aeap_message * ast_aeap_message_deserialize(const struct ast_aeap_message_type *type, const void *buf, intmax_t size)
Deserialize the given buffer into an Asterisk external application message object.
Asterisk external application base message.
enum AST_AEAP_DATA_TYPE serial_type
An Asterisk external application message handler.
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
#define ast_calloc(num, len)
A wrapper for calloc()
AST_AEAP_DATA_TYPE
Supported Asterisk external application data types.
Asterisk external application transport structure to be "derived" by specific transport implementatio...
struct ast_aeap_message * ast_aeap_message_create_error(const struct ast_aeap_message_type *type, const char *name, const char *id, const char *error_msg)
Create an Asterisk external application error response object.
struct ast_aeap_message * msg
const struct ast_aeap_message_handler * response_handlers
const struct ast_aeap_message_type * type
uintmax_t response_handlers_size
const char * ast_aeap_message_error_msg(const struct ast_aeap_message *message)
Retrieve the error message if it has one.
int ast_aeap_message_is_response(const struct ast_aeap_message *message)
Retrieve whether or not this is a response message.
int ast_aeap_send_binary(struct ast_aeap *aeap, const void *buf, uintmax_t size)
Send a binary data to an external application.
ast_aeap_on_message on_message
#define ao2_link(container, obj)
Add an object to a container.