From b44f72f79481f84e7cdc21243ac127e62b9e5ed0 Mon Sep 17 00:00:00 2001 From: Automerge script Date: Mon, 3 Dec 2012 15:19:37 +0000 Subject: Merged revisions 377018,377022 via svnmerge from file:///srv/subversion/repos/asterisk/trunk ................ r377018 | oej | 2012-12-03 08:46:02 -0600 (Mon, 03 Dec 2012) | 5 lines Move functions to AFTER the block of forward declarations of functions. It was a mess. The first part of chan_sip.c is constants, declarations, structures and stuff, then forward declarations and then actual code. It's still a mess, but a bit less messy ;-) ................ r377022 | file | 2012-12-03 08:56:36 -0600 (Mon, 03 Dec 2012) | 13 lines Fix an RTP instance reference count leak in chan_motif. When setting up an RTP instance the RTCP portion of the instance keeps a reference to the instance itself. In order to release this reference and stop RTCP the stop API call must be called before destroying the instance. (closes issue ASTERISK-20751) Reported by: joshoa ........ Merged revisions 377021 from http://svn.asterisk.org/svn/asterisk/branches/11 ................ git-svn-id: https://origsvn.digium.com/svn/asterisk/team/mmichelson/threadpool@377028 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_motif.c | 2 + channels/chan_sip.c | 405 ++++++++++++++++++++++++++------------------------ 2 files changed, 209 insertions(+), 198 deletions(-) diff --git a/channels/chan_motif.c b/channels/chan_motif.c index d56708149..0b07ed158 100644 --- a/channels/chan_motif.c +++ b/channels/chan_motif.c @@ -434,10 +434,12 @@ static void jingle_session_destructor(void *obj) } if (session->rtp) { + ast_rtp_instance_stop(session->rtp); ast_rtp_instance_destroy(session->rtp); } if (session->vrtp) { + ast_rtp_instance_stop(session->vrtp); ast_rtp_instance_destroy(session->vrtp); } diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 2b925373c..3e1e2c45d 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -909,17 +909,6 @@ static const struct { [AST_CC_CCNL] = { AST_CC_CCNL, "NL" }, }; -static enum ast_cc_service_type service_string_to_service_type(const char * const service_string) -{ - enum ast_cc_service_type service; - for (service = AST_CC_CCBS; service <= AST_CC_CCNL; ++service) { - if (!strcasecmp(service_string, sip_cc_service_map[service].service_string)) { - return service; - } - } - return AST_CC_NONE; -} - static const struct { enum sip_cc_notify_state state; const char *state_string; @@ -930,80 +919,6 @@ static const struct { AST_LIST_HEAD_STATIC(epa_static_data_list, epa_backend); -static int sip_epa_register(const struct epa_static_data *static_data) -{ - struct epa_backend *backend = ast_calloc(1, sizeof(*backend)); - - if (!backend) { - return -1; - } - - backend->static_data = static_data; - - AST_LIST_LOCK(&epa_static_data_list); - AST_LIST_INSERT_TAIL(&epa_static_data_list, backend, next); - AST_LIST_UNLOCK(&epa_static_data_list); - return 0; -} - -static void sip_epa_unregister_all(void) -{ - struct epa_backend *backend; - - AST_LIST_LOCK(&epa_static_data_list); - while ((backend = AST_LIST_REMOVE_HEAD(&epa_static_data_list, next))) { - ast_free(backend); - } - AST_LIST_UNLOCK(&epa_static_data_list); -} - -static void cc_handle_publish_error(struct sip_pvt *pvt, const int resp, struct sip_request *req, struct sip_epa_entry *epa_entry); - -static void cc_epa_destructor(void *data) -{ - struct sip_epa_entry *epa_entry = data; - struct cc_epa_entry *cc_entry = epa_entry->instance_data; - ast_free(cc_entry); -} - -static const struct epa_static_data cc_epa_static_data = { - .event = CALL_COMPLETION, - .name = "call-completion", - .handle_error = cc_handle_publish_error, - .destructor = cc_epa_destructor, -}; - -static const struct epa_static_data *find_static_data(const char * const event_package) -{ - const struct epa_backend *backend = NULL; - - AST_LIST_LOCK(&epa_static_data_list); - AST_LIST_TRAVERSE(&epa_static_data_list, backend, next) { - if (!strcmp(backend->static_data->name, event_package)) { - break; - } - } - AST_LIST_UNLOCK(&epa_static_data_list); - return backend ? backend->static_data : NULL; -} - -static struct sip_epa_entry *create_epa_entry (const char * const event_package, const char * const destination) -{ - struct sip_epa_entry *epa_entry; - const struct epa_static_data *static_data; - - if (!(static_data = find_static_data(event_package))) { - return NULL; - } - - if (!(epa_entry = ao2_t_alloc(sizeof(*epa_entry), static_data->destructor, "Allocate new EPA entry"))) { - return NULL; - } - - epa_entry->static_data = static_data; - ast_copy_string(epa_entry->destination, destination, sizeof(epa_entry->destination)); - return epa_entry; -} /*! * Used to create new entity IDs by ESCs. @@ -1043,118 +958,6 @@ static struct event_state_compositor { #endif }; -static const int ESC_MAX_BUCKETS = 37; - -static void esc_entry_destructor(void *obj) -{ - struct sip_esc_entry *esc_entry = obj; - if (esc_entry->sched_id > -1) { - AST_SCHED_DEL(sched, esc_entry->sched_id); - } -} - -static int esc_hash_fn(const void *obj, const int flags) -{ - const struct sip_esc_entry *entry = obj; - return ast_str_hash(entry->entity_tag); -} - -static int esc_cmp_fn(void *obj, void *arg, int flags) -{ - struct sip_esc_entry *entry1 = obj; - struct sip_esc_entry *entry2 = arg; - - return (!strcmp(entry1->entity_tag, entry2->entity_tag)) ? (CMP_MATCH | CMP_STOP) : 0; -} - -static struct event_state_compositor *get_esc(const char * const event_package) { - int i; - for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) { - if (!strcasecmp(event_package, event_state_compositors[i].name)) { - return &event_state_compositors[i]; - } - } - return NULL; -} - -static struct sip_esc_entry *get_esc_entry(const char * entity_tag, struct event_state_compositor *esc) { - struct sip_esc_entry *entry; - struct sip_esc_entry finder; - - ast_copy_string(finder.entity_tag, entity_tag, sizeof(finder.entity_tag)); - - entry = ao2_find(esc->compositor, &finder, OBJ_POINTER); - - return entry; -} - -static int publish_expire(const void *data) -{ - struct sip_esc_entry *esc_entry = (struct sip_esc_entry *) data; - struct event_state_compositor *esc = get_esc(esc_entry->event); - - ast_assert(esc != NULL); - - ao2_unlink(esc->compositor, esc_entry); - ao2_ref(esc_entry, -1); - return 0; -} - -static void create_new_sip_etag(struct sip_esc_entry *esc_entry, int is_linked) -{ - int new_etag = ast_atomic_fetchadd_int(&esc_etag_counter, +1); - struct event_state_compositor *esc = get_esc(esc_entry->event); - - ast_assert(esc != NULL); - if (is_linked) { - ao2_unlink(esc->compositor, esc_entry); - } - snprintf(esc_entry->entity_tag, sizeof(esc_entry->entity_tag), "%d", new_etag); - ao2_link(esc->compositor, esc_entry); -} - -static struct sip_esc_entry *create_esc_entry(struct event_state_compositor *esc, struct sip_request *req, const int expires) -{ - struct sip_esc_entry *esc_entry; - int expires_ms; - - if (!(esc_entry = ao2_alloc(sizeof(*esc_entry), esc_entry_destructor))) { - return NULL; - } - - esc_entry->event = esc->name; - - expires_ms = expires * 1000; - /* Bump refcount for scheduler */ - ao2_ref(esc_entry, +1); - esc_entry->sched_id = ast_sched_add(sched, expires_ms, publish_expire, esc_entry); - - /* Note: This links the esc_entry into the ESC properly */ - create_new_sip_etag(esc_entry, 0); - - return esc_entry; -} - -static int initialize_escs(void) -{ - int i, res = 0; - for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) { - if (!((event_state_compositors[i].compositor) = - ao2_container_alloc(ESC_MAX_BUCKETS, esc_hash_fn, esc_cmp_fn))) { - res = -1; - } - } - return res; -} - -static void destroy_escs(void) -{ - int i; - for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) { - ao2_ref(event_state_compositors[i].compositor, -1); - } -} - struct state_notify_data { int state; struct ao2_container *device_state_info; @@ -1163,6 +966,9 @@ struct state_notify_data { const char *presence_message; }; + +static const int ESC_MAX_BUCKETS = 37; + /*! * \details * Here we implement the container for dialogs which are in the @@ -1302,6 +1108,8 @@ static struct ast_config *notify_types = NULL; /*!< The list of manual NOTIFY (head) = (element)->next; \ } while (0) +struct ao2_container *sip_monitor_instances; + /*---------------------------- Forward declarations of functions in chan_sip.c */ /* Note: This is added to help splitting up chan_sip.c into several files in coming releases. */ @@ -1758,6 +1566,208 @@ static struct ast_cc_agent_callbacks sip_cc_agent_callbacks = { .destructor = sip_cc_agent_destructor, }; +/* -------- End of declarations of structures, constants and forward declarations of functions + Below starts actual code + ------------------------ +*/ + +static int sip_epa_register(const struct epa_static_data *static_data) +{ + struct epa_backend *backend = ast_calloc(1, sizeof(*backend)); + + if (!backend) { + return -1; + } + + backend->static_data = static_data; + + AST_LIST_LOCK(&epa_static_data_list); + AST_LIST_INSERT_TAIL(&epa_static_data_list, backend, next); + AST_LIST_UNLOCK(&epa_static_data_list); + return 0; +} + +static void sip_epa_unregister_all(void) +{ + struct epa_backend *backend; + + AST_LIST_LOCK(&epa_static_data_list); + while ((backend = AST_LIST_REMOVE_HEAD(&epa_static_data_list, next))) { + ast_free(backend); + } + AST_LIST_UNLOCK(&epa_static_data_list); +} + +static void cc_handle_publish_error(struct sip_pvt *pvt, const int resp, struct sip_request *req, struct sip_epa_entry *epa_entry); + +static void cc_epa_destructor(void *data) +{ + struct sip_epa_entry *epa_entry = data; + struct cc_epa_entry *cc_entry = epa_entry->instance_data; + ast_free(cc_entry); +} + +static const struct epa_static_data cc_epa_static_data = { + .event = CALL_COMPLETION, + .name = "call-completion", + .handle_error = cc_handle_publish_error, + .destructor = cc_epa_destructor, +}; + +static const struct epa_static_data *find_static_data(const char * const event_package) +{ + const struct epa_backend *backend = NULL; + + AST_LIST_LOCK(&epa_static_data_list); + AST_LIST_TRAVERSE(&epa_static_data_list, backend, next) { + if (!strcmp(backend->static_data->name, event_package)) { + break; + } + } + AST_LIST_UNLOCK(&epa_static_data_list); + return backend ? backend->static_data : NULL; +} + +static struct sip_epa_entry *create_epa_entry (const char * const event_package, const char * const destination) +{ + struct sip_epa_entry *epa_entry; + const struct epa_static_data *static_data; + + if (!(static_data = find_static_data(event_package))) { + return NULL; + } + + if (!(epa_entry = ao2_t_alloc(sizeof(*epa_entry), static_data->destructor, "Allocate new EPA entry"))) { + return NULL; + } + + epa_entry->static_data = static_data; + ast_copy_string(epa_entry->destination, destination, sizeof(epa_entry->destination)); + return epa_entry; +} +static enum ast_cc_service_type service_string_to_service_type(const char * const service_string) +{ + enum ast_cc_service_type service; + for (service = AST_CC_CCBS; service <= AST_CC_CCNL; ++service) { + if (!strcasecmp(service_string, sip_cc_service_map[service].service_string)) { + return service; + } + } + return AST_CC_NONE; +} + +/* Even state compositors code */ +static void esc_entry_destructor(void *obj) +{ + struct sip_esc_entry *esc_entry = obj; + if (esc_entry->sched_id > -1) { + AST_SCHED_DEL(sched, esc_entry->sched_id); + } +} + +static int esc_hash_fn(const void *obj, const int flags) +{ + const struct sip_esc_entry *entry = obj; + return ast_str_hash(entry->entity_tag); +} + +static int esc_cmp_fn(void *obj, void *arg, int flags) +{ + struct sip_esc_entry *entry1 = obj; + struct sip_esc_entry *entry2 = arg; + + return (!strcmp(entry1->entity_tag, entry2->entity_tag)) ? (CMP_MATCH | CMP_STOP) : 0; +} + +static struct event_state_compositor *get_esc(const char * const event_package) { + int i; + for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) { + if (!strcasecmp(event_package, event_state_compositors[i].name)) { + return &event_state_compositors[i]; + } + } + return NULL; +} + +static struct sip_esc_entry *get_esc_entry(const char * entity_tag, struct event_state_compositor *esc) { + struct sip_esc_entry *entry; + struct sip_esc_entry finder; + + ast_copy_string(finder.entity_tag, entity_tag, sizeof(finder.entity_tag)); + + entry = ao2_find(esc->compositor, &finder, OBJ_POINTER); + + return entry; +} + +static int publish_expire(const void *data) +{ + struct sip_esc_entry *esc_entry = (struct sip_esc_entry *) data; + struct event_state_compositor *esc = get_esc(esc_entry->event); + + ast_assert(esc != NULL); + + ao2_unlink(esc->compositor, esc_entry); + ao2_ref(esc_entry, -1); + return 0; +} + +static void create_new_sip_etag(struct sip_esc_entry *esc_entry, int is_linked) +{ + int new_etag = ast_atomic_fetchadd_int(&esc_etag_counter, +1); + struct event_state_compositor *esc = get_esc(esc_entry->event); + + ast_assert(esc != NULL); + if (is_linked) { + ao2_unlink(esc->compositor, esc_entry); + } + snprintf(esc_entry->entity_tag, sizeof(esc_entry->entity_tag), "%d", new_etag); + ao2_link(esc->compositor, esc_entry); +} + +static struct sip_esc_entry *create_esc_entry(struct event_state_compositor *esc, struct sip_request *req, const int expires) +{ + struct sip_esc_entry *esc_entry; + int expires_ms; + + if (!(esc_entry = ao2_alloc(sizeof(*esc_entry), esc_entry_destructor))) { + return NULL; + } + + esc_entry->event = esc->name; + + expires_ms = expires * 1000; + /* Bump refcount for scheduler */ + ao2_ref(esc_entry, +1); + esc_entry->sched_id = ast_sched_add(sched, expires_ms, publish_expire, esc_entry); + + /* Note: This links the esc_entry into the ESC properly */ + create_new_sip_etag(esc_entry, 0); + + return esc_entry; +} + +static int initialize_escs(void) +{ + int i, res = 0; + for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) { + if (!((event_state_compositors[i].compositor) = + ao2_container_alloc(ESC_MAX_BUCKETS, esc_hash_fn, esc_cmp_fn))) { + res = -1; + } + } + return res; +} + +static void destroy_escs(void) +{ + int i; + for (i = 0; i < ARRAY_LEN(event_state_compositors); i++) { + ao2_ref(event_state_compositors[i].compositor, -1); + } +} + + static int find_by_notify_uri_helper(void *obj, void *arg, int flags) { struct ast_cc_agent *agent = obj; @@ -1940,7 +1950,6 @@ static void sip_cc_agent_destructor(struct ast_cc_agent *agent) ast_free(agent_pvt); } -struct ao2_container *sip_monitor_instances; static int sip_monitor_instance_hash_fn(const void *obj, const int flags) { -- cgit v1.2.3