loader: Add dependency fields to module structures.
[asterisk/asterisk.git] / res / res_pjsip_history.c
index 41c5bdf..40d26d5 100644 (file)
@@ -157,6 +157,9 @@ struct expression_token {
        char field[];
 };
 
+/*! \brief Log level for history output */
+static int log_level = -1;
+
 /*!
  * \brief Operator callback for determining equality
  */
@@ -603,8 +606,13 @@ static void pjsip_history_entry_dtor(void *obj)
        struct pjsip_history_entry *entry = obj;
 
        if (entry->pool) {
-               pj_pool_release(entry->pool);
+               /* This mimics the behavior of pj_pool_safe_release
+                * which was introduced in pjproject 2.6.
+                */
+               pj_pool_t *temp_pool = entry->pool;
+
                entry->pool = NULL;
+               pj_pool_release(temp_pool);
        }
 }
 
@@ -644,6 +652,41 @@ static struct pjsip_history_entry *pjsip_history_entry_alloc(pjsip_msg *msg)
        return entry;
 }
 
+/*! \brief Format single line history entry */
+static void sprint_list_entry(struct pjsip_history_entry *entry, char *line, int len)
+{
+       char addr[64];
+
+       if (entry->transmitted) {
+               pj_sockaddr_print(&entry->dst, addr, sizeof(addr), 3);
+       } else {
+               pj_sockaddr_print(&entry->src, addr, sizeof(addr), 3);
+       }
+
+       if (entry->msg->type == PJSIP_REQUEST_MSG) {
+               char uri[128];
+
+               pjsip_uri_print(PJSIP_URI_IN_REQ_URI, entry->msg->line.req.uri, uri, sizeof(uri));
+               snprintf(line, len, "%-5.5d %-10.10ld %-5.5s %-24.24s %.*s %s SIP/2.0",
+                       entry->number,
+                       entry->timestamp.tv_sec,
+                       entry->transmitted ? "* ==>" : "* <==",
+                       addr,
+                       (int)pj_strlen(&entry->msg->line.req.method.name),
+                       pj_strbuf(&entry->msg->line.req.method.name),
+                       uri);
+       } else {
+               snprintf(line, len, "%-5.5d %-10.10ld %-5.5s %-24.24s SIP/2.0 %u %.*s",
+                       entry->number,
+                       entry->timestamp.tv_sec,
+                       entry->transmitted ? "* ==>" : "* <==",
+                       addr,
+                       entry->msg->line.status.code,
+                       (int)pj_strlen(&entry->msg->line.status.reason),
+                       pj_strbuf(&entry->msg->line.status.reason));
+       }
+}
+
 /*! \brief PJSIP callback when a SIP message is transmitted */
 static pj_status_t history_on_tx_msg(pjsip_tx_data *tdata)
 {
@@ -662,9 +705,19 @@ static pj_status_t history_on_tx_msg(pjsip_tx_data *tdata)
        pj_sockaddr_cp(&entry->dst, &tdata->tp_info.dst_addr);
 
        ast_mutex_lock(&history_lock);
-       AST_VECTOR_APPEND(&vector_history, entry);
+       if (AST_VECTOR_APPEND(&vector_history, entry)) {
+               ao2_ref(entry, -1);
+               entry = NULL;
+       }
        ast_mutex_unlock(&history_lock);
 
+       if (log_level != -1 && entry) {
+               char line[256];
+
+               sprint_list_entry(entry, line, sizeof(line));
+               ast_log_dynamic_level(log_level, "%s\n", line);
+       }
+
        return PJ_SUCCESS;
 }
 
@@ -695,9 +748,19 @@ static pj_bool_t history_on_rx_msg(pjsip_rx_data *rdata)
        }
 
        ast_mutex_lock(&history_lock);
-       AST_VECTOR_APPEND(&vector_history, entry);
+       if (AST_VECTOR_APPEND(&vector_history, entry)) {
+               ao2_ref(entry, -1);
+               entry = NULL;
+       }
        ast_mutex_unlock(&history_lock);
 
+       if (log_level != -1 && entry) {
+               char line[256];
+
+               sprint_list_entry(entry, line, sizeof(line));
+               ast_log_dynamic_level(log_level, "%s\n", line);
+       }
+
        return PJ_FALSE;
 }
 
@@ -902,7 +965,9 @@ static int evaluate_history_entry(struct pjsip_history_entry *entry, struct expr
 
                /* If this is not an operator, push it to the stack */
                if (!it_queue->op) {
-                       AST_VECTOR_APPEND(&stack, it_queue);
+                       if (AST_VECTOR_APPEND(&stack, it_queue)) {
+                               goto error;
+                       }
                        continue;
                }
 
@@ -978,7 +1043,11 @@ static int evaluate_history_entry(struct pjsip_history_entry *entry, struct expr
                if (!result) {
                        goto error;
                }
-               AST_VECTOR_APPEND(&stack, result);
+               if (AST_VECTOR_APPEND(&stack, result)) {
+                       expression_token_free(result);
+
+                       goto error;
+               }
        }
 
        /*
@@ -999,6 +1068,7 @@ static int evaluate_history_entry(struct pjsip_history_entry *entry, struct expr
        }
        result = final->result;
        ast_free(final);
+       AST_VECTOR_FREE(&stack);
 
        return result;
 
@@ -1041,6 +1111,7 @@ static struct vector_history_t *filter_history(struct ast_cli_args *a)
 
        queue = build_expression_queue(a);
        if (!queue) {
+               AST_VECTOR_PTR_FREE(output);
                return NULL;
        }
 
@@ -1061,7 +1132,9 @@ static struct vector_history_t *filter_history(struct ast_cli_args *a)
                } else if (!res) {
                        continue;
                } else {
-                       AST_VECTOR_APPEND(output, ao2_bump(entry));
+                       if (AST_VECTOR_APPEND(output, ao2_bump(entry))) {
+                               ao2_cleanup(entry);
+                       }
                }
        }
        ast_mutex_unlock(&history_lock);
@@ -1118,38 +1191,12 @@ static void display_entry_list(struct ast_cli_args *a, struct vector_history_t *
 
        for (i = 0; i < AST_VECTOR_SIZE(vec); i++) {
                struct pjsip_history_entry *entry;
-               char addr[64];
                char line[256];
 
                entry = AST_VECTOR_GET(vec, i);
+               sprint_list_entry(entry, line, sizeof(line));
 
-               if (entry->transmitted) {
-                       pj_sockaddr_print(&entry->dst, addr, sizeof(addr), 3);
-               } else {
-                       pj_sockaddr_print(&entry->src, addr, sizeof(addr), 3);
-               }
-
-               if (entry->msg->type == PJSIP_REQUEST_MSG) {
-                       char uri[128];
-
-                       pjsip_uri_print(PJSIP_URI_IN_REQ_URI, entry->msg->line.req.uri, uri, sizeof(uri));
-                       snprintf(line, sizeof(line), "%.*s %s SIP/2.0",
-                               (int)pj_strlen(&entry->msg->line.req.method.name),
-                               pj_strbuf(&entry->msg->line.req.method.name),
-                               uri);
-               } else {
-                       snprintf(line, sizeof(line), "SIP/2.0 %u %.*s",
-                               entry->msg->line.status.code,
-                               (int)pj_strlen(&entry->msg->line.status.reason),
-                               pj_strbuf(&entry->msg->line.status.reason));
-               }
-
-               ast_cli(a->fd, "%-5.5d %-10.10ld %-5.5s %-24.24s %s\n",
-                       entry->number,
-                       entry->timestamp.tv_sec,
-                       entry->transmitted ? "* ==>" : "* <==",
-                       addr,
-                       line);
+               ast_cli(a->fd, "%s\n", line);
        }
 }
 
@@ -1233,7 +1280,7 @@ static char *pjsip_show_history(struct ast_cli_entry *e, int cmd, struct ast_cli
                }
                entry = ao2_bump(AST_VECTOR_GET(vec, 0));
                if (vec == &vector_history) {
-                       ast_mutex_lock(&history_lock);
+                       ast_mutex_unlock(&history_lock);
                }
        }
 
@@ -1319,6 +1366,11 @@ static int load_module(void)
 {
        CHECK_PJSIP_MODULE_LOADED();
 
+       log_level = ast_logger_register_level("PJSIP_HISTORY");
+       if (log_level < 0) {
+               ast_log(LOG_WARNING, "Unable to register history log level\n");
+       }
+
        pj_caching_pool_init(&cachingpool, &pj_pool_factory_default_policy, 0);
 
        AST_VECTOR_INIT(&vector_history, HISTORY_INITIAL_SIZE);
@@ -1339,6 +1391,10 @@ static int unload_module(void)
 
        pj_caching_pool_destroy(&cachingpool);
 
+       if (log_level != -1) {
+               ast_logger_unregister_level("PJSIP_HISTORY");
+       }
+
        return 0;
 }
 
@@ -1347,4 +1403,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP History",
                .load = load_module,
                .unload = unload_module,
                .load_pri = AST_MODPRI_APP_DEPEND,
+               .requires = "res_pjsip",
        );