diff --git a/include/asterisk/event.h b/include/asterisk/event.h index 5ffef1f35c48b99990f916f9c68aac41fd245dde..c5805f31a2a60b68ac12cdacfb6ea1482a2b95b2 100644 --- a/include/asterisk/event.h +++ b/include/asterisk/event.h @@ -331,6 +331,9 @@ void ast_event_dump_cache(const struct ast_event_sub *event_sub); * because it makes no sense to do so. So, a payload must also be specified * after the IE payload type. * + * \note The EID IE will be appended automatically when this function is used + * with at least one IE specified. + * * \return This returns the event that has been created. If there is an error * creating the event, NULL will be returned. * @@ -508,6 +511,19 @@ int ast_event_append_ie_bitflags(struct ast_event **event, enum ast_event_ie_typ int ast_event_append_ie_raw(struct ast_event **event, enum ast_event_ie_type ie_type, const void *data, size_t data_len); +/*! + * \brief Append the global EID IE + * + * \param event the event to append IE to + * + * \note For ast_event_new() that includes IEs, this is done automatically + * for you. + * + * \retval 0 success + * \retval -1 failure + */ +int ast_event_append_eid(struct ast_event **event); + /*! * \brief Get the value of an information element that has an integer payload * diff --git a/main/event.c b/main/event.c index 7a953c5087151220d48816218928b6da3000dd23..673f8a11cb6691167d06fe94c0fa4e89deba1bfa 100644 --- a/main/event.c +++ b/main/event.c @@ -913,7 +913,7 @@ struct ast_event_sub *ast_event_unsubscribe(struct ast_event_sub *sub) void ast_event_iterator_init(struct ast_event_iterator *iterator, const struct ast_event *event) { - iterator->event_len = ntohs(event->event_len); + iterator->event_len = ast_event_get_size(event); iterator->event = event; iterator->ie = (struct ast_event_ie *) ( ((char *) event) + sizeof(*event) ); } @@ -1159,12 +1159,18 @@ struct ast_event *ast_event_new(enum ast_event_type type, ...) if (has_ie && !ast_event_get_ie_raw(event, AST_EVENT_IE_EID)) { /* If the event is originating on this server, add the server's * entity ID to the event. */ - ast_event_append_ie_raw(&event, AST_EVENT_IE_EID, &ast_eid_default, sizeof(ast_eid_default)); + ast_event_append_eid(&event); } return event; } +int ast_event_append_eid(struct ast_event **event) +{ + return ast_event_append_ie_raw(event, AST_EVENT_IE_EID, + &ast_eid_default, sizeof(ast_eid_default)); +} + void ast_event_destroy(struct ast_event *event) { ast_free(event); diff --git a/tests/test_event.c b/tests/test_event.c new file mode 100644 index 0000000000000000000000000000000000000000..77a641726e9f85698d32067be7584582b4eb89b2 --- /dev/null +++ b/tests/test_event.c @@ -0,0 +1,194 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2010, Digium, Inc. + * + * Russell Bryant <russell@digium.com> + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! + * \file + * \brief Tests for the ast_event API + * + * \author Russell Bryant <russell@digium.com> + * + * \ingroup tests + */ + +/*** MODULEINFO + <depend>TEST_FRAMEWORK</depend> + ***/ + +#include "asterisk.h" + +ASTERISK_FILE_VERSION(__FILE__, "$Revision$") + +#include "asterisk/module.h" +#include "asterisk/utils.h" +#include "asterisk/test.h" +#include "asterisk/event.h" + +static int check_event(struct ast_event *event, struct ast_test *test, + enum ast_event_type expected_type, const char *str, + uint32_t uint) +{ + enum ast_event_type type; + const void *foo; + + /* Check #1: Ensure event type is set properly. */ + type = ast_event_get_type(event); + if (ast_event_get_type(event) != type) { + ast_test_status_update(test, "Expected event type: '%d', got '%d'\n", + expected_type, type); + return -1; + } + + /* Check #2: Check for automatically included EID */ + if (memcmp(&ast_eid_default, ast_event_get_ie_raw(event, AST_EVENT_IE_EID), sizeof(ast_eid_default))) { + ast_test_status_update(test, "Failed to get EID\n"); + return -1; + } + + /* Check #3: Check for the string IE */ + if (strcmp(str, ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX))) { + ast_test_status_update(test, "Failed to get string IE.\n"); + return -1; + } + + /* Check #4: Check for the uint IE */ + if (uint != ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS)) { + ast_test_status_update(test, "Failed to get uint IE.\n"); + return -1; + } + + /* Check #5: Check if a check for a str IE that isn't there works */ + if ((foo = ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE))) { + ast_test_status_update(test, "DEVICE IE check returned non-NULL %p\n", foo); + return -1; + } + + /* Check #6: Check if a check for a uint IE that isn't there returns 0 */ + if (ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS)) { + ast_test_status_update(test, "OLDMSGS IE should be 0\n"); + return -1; + } + + ast_test_status_update(test, "Event looks good.\n"); + + return 0; +} + +AST_TEST_DEFINE(event_new_test) +{ + enum ast_test_result_state res = AST_TEST_PASS; + struct ast_event *event = NULL; + + static const enum ast_event_type type = AST_EVENT_CUSTOM; + static const char str[] = "SIP/alligatormittens"; + static const uint32_t uint = 0xb00bface; + + switch (cmd) { + case TEST_INIT: + info->name = "ast_event_new_test"; + info->category = "main/event/"; + info->summary = "Test event creation"; + info->description = + "This test exercises the API calls that allow allocation " + "of an ast_event." + "\n"; + return AST_TEST_NOT_RUN; + case TEST_EXECUTE: + break; + } + + /* + * Test 2 methods of event creation: + * + * 1) Dynamic via appending each IE individually. + * 2) Statically, with all IEs in ast_event_new(). + */ + + ast_test_status_update(test, "First, test dynamic event creation...\n"); + + if (!(event = ast_event_new(type, AST_EVENT_IE_END))) { + ast_test_status_update(test, "Failed to allocate ast_event object.\n"); + res = AST_TEST_FAIL; + goto return_cleanup; + } + + if (ast_event_append_ie_str(&event, AST_EVENT_IE_MAILBOX, str)) { + ast_test_status_update(test, "Failed to append str IE\n"); + res = AST_TEST_FAIL; + goto return_cleanup; + } + + if (ast_event_append_ie_uint(&event, AST_EVENT_IE_NEWMSGS, uint)) { + ast_test_status_update(test, "Failed to append uint IE\n"); + res = AST_TEST_FAIL; + goto return_cleanup; + } + + if (ast_event_append_eid(&event)) { + ast_test_status_update(test, "Failed to append EID\n"); + res = AST_TEST_FAIL; + goto return_cleanup; + } + + if (check_event(event, test, type, str, uint)) { + ast_test_status_update(test, "Dynamically generated event broken\n"); + res = AST_TEST_FAIL; + goto return_cleanup; + } + + ast_event_destroy(event); + event = NULL; + + event = ast_event_new(type, + AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, str, + AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, uint, + AST_EVENT_IE_END); + + if (!event) { + ast_test_status_update(test, "Failed to allocate ast_event object.\n"); + res = AST_TEST_FAIL; + goto return_cleanup; + } + + if (check_event(event, test, type, str, uint)) { + ast_test_status_update(test, "Statically generated event broken\n"); + res = AST_TEST_FAIL; + goto return_cleanup; + } + +return_cleanup: + if (event) { + ast_event_destroy(event); + event = NULL; + } + + return res; +} + +static int unload_module(void) +{ + AST_TEST_UNREGISTER(event_new_test); + return 0; +} + +static int load_module(void) +{ + AST_TEST_REGISTER(event_new_test); + return AST_MODULE_LOAD_SUCCESS; +} + +AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "ast_event API Tests");