Merge "res_pjsip: New endpoint option "refer_blind_progress""
[asterisk/asterisk.git] / res / res_pjsip_history.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2015, Digium, Inc.
5  *
6  * Matt Jordan <mjordan@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*!
20  * \file
21  * \brief PJSIP History
22  *
23  * \author Matt Jordan <mjordan@digium.com>
24  *
25  */
26
27 /*** MODULEINFO
28         <depend>pjproject</depend>
29         <depend>res_pjsip</depend>
30         <support_level>extended</support_level>
31  ***/
32
33 #include "asterisk.h"
34
35 #include <pjsip.h>
36 #include <regex.h>
37
38 #include "asterisk/res_pjsip.h"
39 #include "asterisk/module.h"
40 #include "asterisk/logger.h"
41 #include "asterisk/cli.h"
42 #include "asterisk/netsock2.h"
43 #include "asterisk/vector.h"
44 #include "asterisk/lock.h"
45
46 #define HISTORY_INITIAL_SIZE 256
47
48 /*! \brief Pool factory used by pjlib to allocate memory. */
49 static pj_caching_pool cachingpool;
50
51 /*! \brief Whether or not we are storing history */
52 static int enabled;
53
54 /*! \brief Packet count */
55 static int packet_number;
56
57 /*! \brief An item in the history */
58 struct pjsip_history_entry {
59         /*! \brief Packet number */
60         int number;
61         /*! \brief Whether or not we transmitted the packet */
62         int transmitted;
63         /*! \brief Time the packet was transmitted/received */
64         struct timeval timestamp;
65         /*! \brief Source address */
66         pj_sockaddr_in src;
67         /*! \brief Destination address */
68         pj_sockaddr_in dst;
69         /*! \brief Memory pool used to allocate \c msg */
70         pj_pool_t *pool;
71         /*! \brief The actual SIP message */
72         pjsip_msg *msg;
73 };
74
75 /*! \brief Mutex that protects \ref vector_history */
76 AST_MUTEX_DEFINE_STATIC(history_lock);
77
78 /*! \brief The one and only history that we've captured */
79 static AST_VECTOR(vector_history_t, struct pjsip_history_entry *) vector_history;
80
81 struct expression_token;
82
83 /*! \brief An operator that we understand in an expression */
84 struct operator {
85         /*! \brief Our operator's symbol */
86         const char *symbol;
87         /*! \brief Precedence of the symbol */
88         int precedence;
89         /*! \brief Non-zero if the operator is evaluated right-to-left */
90         int right_to_left;
91         /*! \brief Number of operands the operator takes */
92         int operands;
93         /*!
94          * \brief Evaluation function for unary operators
95          *
96          * \param op The operator being evaluated
97          * \param type The type of value contained in \c operand
98          * \param operand A pointer to the value to evaluate
99          *
100          * \retval -1 error
101          * \retval 0 evaluation is False
102          * \retval 1 evaluation is True
103          */
104         int (* const evaluate_unary)(struct operator *op, enum aco_option_type type, void *operand);
105         /*!
106          * \brief Evaluation function for binary operators
107          *
108          * \param op The operator being evaluated
109          * \param type The type of value contained in \c op_left
110          * \param op_left A pointer to the value to evaluate (a result or extracted from an entry)
111          * \param op_right The expression token containing the other value (a result or user-provided)
112          *
113          * \retval -1 error
114          * \retval 0 evaluation is False
115          * \retval 1 evaluation is True
116          */
117         int (* const evaluate)(struct operator *op, enum aco_option_type type, void *op_left, struct expression_token *op_right);
118 };
119
120 /*! \brief A field that we understand and can perform operations on */
121 struct allowed_field {
122         /*! \brief The representation of the field */
123         const char *symbol;
124         /*! \brief The type /c get_field returns */
125         enum aco_option_type return_type;
126         /*!
127          * \brief Function that returns the field from a pjsip_history_entry
128          *
129          * Note that the function must return a pointer to the location in
130          * \c pjsip_history_entry - no memory should be allocated as the caller
131          * will not dispose of any
132          */
133         void *(* const get_field)(struct pjsip_history_entry *entry);
134 };
135
136 /*! \brief The type of token that has been parsed out of an expression */
137 enum expression_token_type {
138         /*! The \c expression_token contains a field */
139         TOKEN_TYPE_FIELD,
140         /*! The \c expression_token contains an operator */
141         TOKEN_TYPE_OPERATOR,
142         /*! The \c expression_token contains a previous result */
143         TOKEN_TYPE_RESULT
144 };
145
146 /*! \brief A token in the expression or an evaluated part of the expression */
147 struct expression_token {
148         /*! \brief The next expression token in the queue */
149         struct expression_token *next;
150         /*! \brief The type of value stored in the expression token */
151         enum expression_token_type token_type;
152         /*! \brief An operator that evaluates expressions */
153         struct operator *op;
154         /*! \brief The result of an evaluated expression */
155         int result;
156         /*! \brief The field in the expression */
157         char field[];
158 };
159
160 /*! \brief Log level for history output */
161 static int log_level = -1;
162
163 /*!
164  * \brief Operator callback for determining equality
165  */
166 static int evaluate_equal(struct operator *op, enum aco_option_type type, void *op_left, struct expression_token *op_right)
167 {
168         switch (type) {
169         case OPT_BOOL_T:
170         case OPT_BOOLFLAG_T:
171         case OPT_INT_T:
172         case OPT_UINT_T:
173         {
174                 int right;
175
176                 if (sscanf(op_right->field, "%30d", &right) != 1) {
177                         ast_log(LOG_WARNING, "Unable to extract field '%s': not an integer\n", op_right->field);
178                         return -1;
179                 }
180                 return (*(int *)op_left) == right;
181         }
182         case OPT_DOUBLE_T:
183         {
184                 double right;
185
186                 if (sscanf(op_right->field, "%lf", &right) != 1) {
187                         ast_log(LOG_WARNING, "Unable to extract field '%s': not a double\n", op_right->field);
188                         return -1;
189                 }
190                 return (*(double *)op_left) == right;
191         }
192         case OPT_CHAR_ARRAY_T:
193         case OPT_STRINGFIELD_T:
194                 /* In our case, we operate on pj_str_t */
195                 return pj_strcmp2(op_left, op_right->field) == 0;
196         case OPT_NOOP_T:
197         /* Used for timeval */
198         {
199                 struct timeval right = { 0, };
200
201                 if (sscanf(op_right->field, "%ld", &right.tv_sec) != 1) {
202                         ast_log(LOG_WARNING, "Unable to extract field '%s': not a timestamp\n", op_right->field);
203                         return -1;
204                 }
205
206                 return ast_tvcmp(*(struct timeval *)op_left, right) == 0;
207         }
208         case OPT_SOCKADDR_T:
209         /* In our case, we operate only on pj_sockaddr_t */
210         {
211                 pj_sockaddr right;
212                 pj_str_t str_right;
213
214                 pj_cstr(&str_right, op_right->field);
215                 if (pj_sockaddr_parse(pj_AF_UNSPEC(), 0, &str_right, &right) != PJ_SUCCESS) {
216                         ast_log(LOG_WARNING, "Unable to convert field '%s': not an IPv4 or IPv6 address\n", op_right->field);
217                         return -1;
218                 }
219
220                 return pj_sockaddr_cmp(op_left, &right) == 0;
221         }
222         default:
223                 ast_log(LOG_WARNING, "Cannot evaluate field '%s': invalid type for operator '%s'\n",
224                         op_right->field, op->symbol);
225         }
226
227         return -1;
228 }
229
230 /*!
231  * \brief Operator callback for determining inequality
232  */
233 static int evaluate_not_equal(struct operator *op, enum aco_option_type type, void *op_left, struct expression_token *op_right)
234 {
235         return !evaluate_equal(op, type, op_left, op_right);
236 }
237
238 /*
239  * \brief Operator callback for determining if one operand is less than another
240  */
241 static int evaluate_less_than(struct operator *op, enum aco_option_type type, void *op_left, struct expression_token *op_right)
242 {
243         switch (type) {
244         case OPT_BOOL_T:
245         case OPT_BOOLFLAG_T:
246         case OPT_INT_T:
247         case OPT_UINT_T:
248         {
249                 int right;
250
251                 if (sscanf(op_right->field, "%30d", &right) != 1) {
252                         ast_log(LOG_WARNING, "Unable to extract field '%s': not an integer\n", op_right->field);
253                         return -1;
254                 }
255                 return (*(int *)op_left) < right;
256         }
257         case OPT_DOUBLE_T:
258         {
259                 double right;
260
261                 if (sscanf(op_right->field, "%lf", &right) != 1) {
262                         ast_log(LOG_WARNING, "Unable to extract field '%s': not a double\n", op_right->field);
263                         return -1;
264                 }
265                 return (*(double *)op_left) < right;
266         }
267         case OPT_NOOP_T:
268         /* Used for timeval */
269         {
270                 struct timeval right = { 0, };
271
272                 if (sscanf(op_right->field, "%ld", &right.tv_sec) != 1) {
273                         ast_log(LOG_WARNING, "Unable to extract field '%s': not a timestamp\n", op_right->field);
274                         return -1;
275                 }
276
277                 return ast_tvcmp(*(struct timeval *)op_left, right) == -1;
278         }
279         default:
280                 ast_log(LOG_WARNING, "Cannot evaluate field '%s': invalid type for operator '%s'\n",
281                         op_right->field, op->symbol);
282         }
283
284         return -1;
285 }
286
287 /*
288  * \brief Operator callback for determining if one operand is greater than another
289  */
290 static int evaluate_greater_than(struct operator *op, enum aco_option_type type, void *op_left, struct expression_token *op_right)
291 {
292         switch (type) {
293         case OPT_BOOL_T:
294         case OPT_BOOLFLAG_T:
295         case OPT_INT_T:
296         case OPT_UINT_T:
297         {
298                 int right;
299
300                 if (sscanf(op_right->field, "%30d", &right) != 1) {
301                         ast_log(LOG_WARNING, "Unable to extract field '%s': not an integer\n", op_right->field);
302                         return -1;
303                 }
304                 return (*(int *)op_left) > right;
305         }
306         case OPT_DOUBLE_T:
307         {
308                 double right;
309
310                 if (sscanf(op_right->field, "%lf", &right) != 1) {
311                         ast_log(LOG_WARNING, "Unable to extract field '%s': not a double\n", op_right->field);
312                         return -1;
313                 }
314                 return (*(double *)op_left) > right;
315         }
316         case OPT_NOOP_T:
317         /* Used for timeval */
318         {
319                 struct timeval right = { 0, };
320
321                 if (sscanf(op_right->field, "%ld", &right.tv_sec) != 1) {
322                         ast_log(LOG_WARNING, "Unable to extract field '%s': not a timestamp\n", op_right->field);
323                         return -1;
324                 }
325
326                 return ast_tvcmp(*(struct timeval *)op_left, right) == 1;
327         }
328         default:
329                 ast_log(LOG_WARNING, "Cannot evaluate field '%s': invalid type for operator '%s'\n",
330                         op_right->field, op->symbol);
331         }
332
333         return -1;
334 }
335
336 /*
337  * \brief Operator callback for determining if one operand is less than or equal to another
338  */
339 static int evaluate_less_than_or_equal(struct operator *op, enum aco_option_type type, void *op_left, struct expression_token *op_right)
340 {
341         return !evaluate_greater_than(op, type, op_left, op_right);
342 }
343
344 /*
345  * \brief Operator callback for determining if one operand is greater than or equal to another
346  */
347 static int evaluate_greater_than_or_equal(struct operator *op, enum aco_option_type type, void *op_left, struct expression_token *op_right)
348 {
349         return !evaluate_less_than(op, type, op_left, op_right);
350 }
351
352 /*
353  * \brief Operator callback for determining logical NOT
354  */
355 static int evaluate_not(struct operator *op, enum aco_option_type type, void *operand)
356 {
357         switch (type) {
358         case OPT_BOOL_T:
359         case OPT_BOOLFLAG_T:
360         case OPT_INT_T:
361         case OPT_UINT_T:
362                 return !(*(int *)operand);
363         default:
364                 ast_log(LOG_WARNING, "Cannot evaluate: invalid operand type for operator '%s'\n", op->symbol);
365         }
366
367         return -1;
368 }
369
370 /*
371  * \brief Operator callback for determining logical AND
372  */
373 static int evaluate_and(struct operator *op, enum aco_option_type type, void *op_left, struct expression_token *op_right)
374 {
375         switch (type) {
376         case OPT_BOOL_T:
377         case OPT_BOOLFLAG_T:
378         case OPT_INT_T:
379         case OPT_UINT_T:
380                 return (*(int *)op_left && op_right->result);
381         default:
382                 ast_log(LOG_WARNING, "Cannot evaluate: invalid operand type for operator '%s'\n", op->symbol);
383         }
384
385         return -1;
386 }
387
388 /*
389  * \brief Operator callback for determining logical OR
390  */
391 static int evaluate_or(struct operator *op, enum aco_option_type type, void *op_left, struct expression_token *op_right)
392 {
393         switch (type) {
394         case OPT_BOOL_T:
395         case OPT_BOOLFLAG_T:
396         case OPT_INT_T:
397         case OPT_UINT_T:
398                 return (*(int *)op_left || op_right->result);
399         default:
400                 ast_log(LOG_WARNING, "Cannot evaluate: invalid operand type for operator '%s'\n", op->symbol);
401         }
402
403         return -1;
404 }
405
406 /*
407  * \brief Operator callback for regex 'like'
408  */
409 static int evaluate_like(struct operator *op, enum aco_option_type type, void *op_left, struct expression_token *op_right)
410 {
411         switch (type) {
412         case OPT_CHAR_ARRAY_T:
413         case OPT_STRINGFIELD_T:
414         /* In our case, we operate on pj_str_t */
415         {
416                 int result;
417                 regex_t regexbuf;
418                 char buf[pj_strlen(op_left) + 1];
419
420                 ast_copy_pj_str(buf, op_left, pj_strlen(op_left));
421                 if (regcomp(&regexbuf, op_right->field, REG_EXTENDED | REG_NOSUB)) {
422                         ast_log(LOG_WARNING, "Failed to compile '%s' into a regular expression\n", op_right->field);
423                         return -1;
424                 }
425
426                 result = (regexec(&regexbuf, buf, 0, NULL, 0) == 0);
427                 regfree(&regexbuf);
428
429                 return result;
430         }
431         default:
432                 ast_log(LOG_WARNING, "Cannot evaluate: invalid operand type for operator '%s'\n", op->symbol);
433         }
434
435         return -1;
436 }
437
438 /*!
439  * \brief Operator token for a left parenthesis.
440  *
441  * While this is used by the shunting-yard algorithm implementation,
442  * it should never appear in the resulting RPN queue of expression tokens
443  */
444 static struct operator left_paren = {
445         .symbol = "(",
446         .precedence = 15
447 };
448
449 /*!
450  * \brief Our allowed operations
451  */
452 static struct operator allowed_operators[] = {
453         { .symbol = "=", .precedence = 7, .operands = 2, .evaluate = evaluate_equal, },
454         { .symbol = "==", .precedence = 7, .operands = 2, .evaluate = evaluate_equal, },
455         { .symbol = "!=", .precedence = 7, .operands = 2, .evaluate = evaluate_not_equal, },
456         { .symbol = "<", .precedence = 6, .operands = 2, .evaluate = evaluate_less_than, },
457         { .symbol = ">", .precedence = 6, .operands = 2, .evaluate = evaluate_greater_than, },
458         { .symbol = "<=", .precedence = 6, .operands = 2, .evaluate = evaluate_less_than_or_equal, },
459         { .symbol = ">=", .precedence = 6, .operands = 2, .evaluate = evaluate_greater_than_or_equal, },
460         { .symbol = "!", .precedence = 2, .operands = 1, .right_to_left = 1, .evaluate_unary = evaluate_not, },
461         { .symbol = "&&", .precedence = 11, .operands = 2, .evaluate = evaluate_and, },
462         { .symbol = "||", .precedence = 12, .operands = 2, .evaluate = evaluate_or, },
463         { .symbol = "like", .precedence = 7, .operands = 2, .evaluate = evaluate_like, },
464         { .symbol = "and", .precedence = 11, .operands = 2, .evaluate = evaluate_and, },
465         { .symbol = "or", .precedence = 11, .operands = 2, .evaluate = evaluate_or, },
466         { .symbol = "not", .precedence = 2, .operands = 1, .right_to_left = 1, .evaluate_unary = evaluate_not, },
467 };
468
469 /*! \brief Callback to retrieve the entry index number */
470 static void *entry_get_number(struct pjsip_history_entry *entry)
471 {
472         return &entry->number;
473 }
474
475 /*! \brief Callback to retrieve the entry's timestamp */
476 static void *entry_get_timestamp(struct pjsip_history_entry *entry)
477 {
478         return &entry->timestamp;
479 }
480
481 /*! \brief Callback to retrieve the entry's destination address */
482 static void *entry_get_addr(struct pjsip_history_entry *entry)
483 {
484         if (entry->transmitted) {
485                 return &entry->dst;
486         } else {
487                 return &entry->src;
488         }
489 }
490
491 /*! \brief Callback to retrieve the entry's SIP request method type */
492 static void *entry_get_sip_msg_request_method(struct pjsip_history_entry *entry)
493 {
494         if (entry->msg->type != PJSIP_REQUEST_MSG) {
495                 return NULL;
496         }
497
498         return &entry->msg->line.req.method.name;
499 }
500
501 /*! \brief Callback to retrieve the entry's SIP Call-ID header */
502 static void *entry_get_sip_msg_call_id(struct pjsip_history_entry *entry)
503 {
504         pjsip_cid_hdr *cid_hdr;
505
506         cid_hdr = PJSIP_MSG_CID_HDR(entry->msg);
507
508         return &cid_hdr->id;
509 }
510
511 /*! \brief The fields we allow */
512 static struct allowed_field allowed_fields[] = {
513         { .symbol = "number", .return_type = OPT_INT_T, .get_field = entry_get_number, },
514         /* We co-op the NOOP type here for timeval */
515         { .symbol = "timestamp", .return_type = OPT_NOOP_T, .get_field = entry_get_timestamp, },
516         { .symbol = "addr", .return_type = OPT_SOCKADDR_T, .get_field = entry_get_addr, },
517         { .symbol = "sip.msg.request.method", .return_type = OPT_CHAR_ARRAY_T, .get_field = entry_get_sip_msg_request_method, },
518         { .symbol = "sip.msg.call-id", .return_type = OPT_CHAR_ARRAY_T, .get_field = entry_get_sip_msg_call_id, },
519 };
520
521 /*! \brief Free an expression token and all others it references */
522 static struct expression_token *expression_token_free(struct expression_token *token)
523 {
524         struct expression_token *it_token;
525
526         it_token = token;
527         while (it_token) {
528                 struct expression_token *prev = it_token;
529
530                 it_token = it_token->next;
531                 ast_free(prev);
532         }
533
534         return NULL;
535 }
536
537 /*!
538  * \brief Allocate an expression token
539  *
540  * \param token_type The type of token in the expression
541  * \param value The value/operator/result to pack into the token
542  *
543  * \retval NULL on failure
544  * \retval \c expression_token on success
545  */
546 static struct expression_token *expression_token_alloc(enum expression_token_type token_type, void *value)
547 {
548         struct expression_token *token;
549
550         switch (token_type) {
551         case TOKEN_TYPE_RESULT:
552         case TOKEN_TYPE_OPERATOR:
553                 token = ast_calloc(1, sizeof(*token));
554                 break;
555         case TOKEN_TYPE_FIELD:
556                 token = ast_calloc(1, sizeof(*token) + strlen((const char *)value) + 1);
557                 break;
558         default:
559                 ast_assert(0);
560                 return NULL;
561         }
562
563         if (!token) {
564                 return NULL;
565         }
566         token->token_type = token_type;
567
568         switch (token_type) {
569         case TOKEN_TYPE_RESULT:
570                 token->result = *(int *)value;
571                 break;
572         case TOKEN_TYPE_OPERATOR:
573                 token->op = value;
574                 break;
575         case TOKEN_TYPE_FIELD:
576                 strcpy(token->field, value); /* safe */
577                 break;
578         default:
579                 ast_assert(0);
580         }
581
582         return token;
583 }
584
585 /*! \brief Determine if the expression token matches a field in \c allowed_fields */
586 static struct allowed_field *get_allowed_field(struct expression_token *token)
587 {
588         int i;
589
590         ast_assert(token->token_type == TOKEN_TYPE_FIELD);
591
592         for (i = 0; i < ARRAY_LEN(allowed_fields); i++) {
593                 if (strcasecmp(allowed_fields[i].symbol, token->field)) {
594                         continue;
595                 }
596
597                 return &allowed_fields[i];
598         }
599
600         return NULL;
601 }
602
603 /*! \brief AO2 destructor for \c pjsip_history_entry */
604 static void pjsip_history_entry_dtor(void *obj)
605 {
606         struct pjsip_history_entry *entry = obj;
607
608         if (entry->pool) {
609                 /* This mimics the behavior of pj_pool_safe_release
610                  * which was introduced in pjproject 2.6.
611                  */
612                 pj_pool_t *temp_pool = entry->pool;
613
614                 entry->pool = NULL;
615                 pj_pool_release(temp_pool);
616         }
617 }
618
619 /*!
620  * \brief Create a \c pjsip_history_entry AO2 object
621  *
622  * \param msg The PJSIP message that this history entry wraps
623  *
624  * \retval An AO2 \c pjsip_history_entry object on success
625  * \retval NULL on failure
626  */
627 static struct pjsip_history_entry *pjsip_history_entry_alloc(pjsip_msg *msg)
628 {
629         struct pjsip_history_entry *entry;
630
631         entry = ao2_alloc_options(sizeof(*entry), pjsip_history_entry_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK);
632         if (!entry) {
633                 return NULL;
634         }
635         entry->number = ast_atomic_fetchadd_int(&packet_number, 1);
636         entry->timestamp = ast_tvnow();
637         entry->timestamp.tv_usec = 0;
638
639         entry->pool = pj_pool_create(&cachingpool.factory, NULL, PJSIP_POOL_RDATA_LEN,
640                                      PJSIP_POOL_RDATA_INC, NULL);
641         if (!entry->pool) {
642                 ao2_ref(entry, -1);
643                 return NULL;
644         }
645
646         entry->msg = pjsip_msg_clone(entry->pool, msg);
647         if (!entry->msg) {
648                 ao2_ref(entry, -1);
649                 return NULL;
650         }
651
652         return entry;
653 }
654
655 /*! \brief Format single line history entry */
656 static void sprint_list_entry(struct pjsip_history_entry *entry, char *line, int len)
657 {
658         char addr[64];
659
660         if (entry->transmitted) {
661                 pj_sockaddr_print(&entry->dst, addr, sizeof(addr), 3);
662         } else {
663                 pj_sockaddr_print(&entry->src, addr, sizeof(addr), 3);
664         }
665
666         if (entry->msg->type == PJSIP_REQUEST_MSG) {
667                 char uri[128];
668
669                 pjsip_uri_print(PJSIP_URI_IN_REQ_URI, entry->msg->line.req.uri, uri, sizeof(uri));
670                 snprintf(line, len, "%-5.5d %-10.10ld %-5.5s %-24.24s %.*s %s SIP/2.0",
671                         entry->number,
672                         entry->timestamp.tv_sec,
673                         entry->transmitted ? "* ==>" : "* <==",
674                         addr,
675                         (int)pj_strlen(&entry->msg->line.req.method.name),
676                         pj_strbuf(&entry->msg->line.req.method.name),
677                         uri);
678         } else {
679                 snprintf(line, len, "%-5.5d %-10.10ld %-5.5s %-24.24s SIP/2.0 %u %.*s",
680                         entry->number,
681                         entry->timestamp.tv_sec,
682                         entry->transmitted ? "* ==>" : "* <==",
683                         addr,
684                         entry->msg->line.status.code,
685                         (int)pj_strlen(&entry->msg->line.status.reason),
686                         pj_strbuf(&entry->msg->line.status.reason));
687         }
688 }
689
690 /*! \brief PJSIP callback when a SIP message is transmitted */
691 static pj_status_t history_on_tx_msg(pjsip_tx_data *tdata)
692 {
693         struct pjsip_history_entry *entry;
694
695         if (!enabled) {
696                 return PJ_SUCCESS;
697         }
698
699         entry = pjsip_history_entry_alloc(tdata->msg);
700         if (!entry) {
701                 return PJ_SUCCESS;
702         }
703         entry->transmitted = 1;
704         pj_sockaddr_cp(&entry->src, &tdata->tp_info.transport->local_addr);
705         pj_sockaddr_cp(&entry->dst, &tdata->tp_info.dst_addr);
706
707         ast_mutex_lock(&history_lock);
708         AST_VECTOR_APPEND(&vector_history, entry);
709         ast_mutex_unlock(&history_lock);
710
711         if (log_level != -1) {
712                 char line[256];
713
714                 sprint_list_entry(entry, line, sizeof(line));
715                 ast_log_dynamic_level(log_level, "%s\n", line);
716         }
717
718         return PJ_SUCCESS;
719 }
720
721 /*! \brief PJSIP callback when a SIP message is received */
722 static pj_bool_t history_on_rx_msg(pjsip_rx_data *rdata)
723 {
724         struct pjsip_history_entry *entry;
725
726         if (!enabled) {
727                 return PJ_FALSE;
728         }
729
730         if (!rdata->msg_info.msg) {
731                 return PJ_FALSE;
732         }
733
734         entry = pjsip_history_entry_alloc(rdata->msg_info.msg);
735         if (!entry) {
736                 return PJ_FALSE;
737         }
738
739         if (rdata->tp_info.transport->addr_len) {
740                 pj_sockaddr_cp(&entry->dst, &rdata->tp_info.transport->local_addr);
741         }
742
743         if (rdata->pkt_info.src_addr_len) {
744                 pj_sockaddr_cp(&entry->src, &rdata->pkt_info.src_addr);
745         }
746
747         ast_mutex_lock(&history_lock);
748         AST_VECTOR_APPEND(&vector_history, entry);
749         ast_mutex_unlock(&history_lock);
750
751         if (log_level != -1) {
752                 char line[256];
753
754                 sprint_list_entry(entry, line, sizeof(line));
755                 ast_log_dynamic_level(log_level, "%s\n", line);
756         }
757
758         return PJ_FALSE;
759 }
760
761 /*! \brief Vector callback that releases the reference for the entry in a history vector */
762 static void clear_history_entry_cb(struct pjsip_history_entry *entry)
763 {
764         ao2_ref(entry, -1);
765 }
766
767 /*!
768  * \brief Remove all entries from \ref vector_history
769  *
770  * This must be called from a registered PJSIP thread
771  */
772 static int clear_history_entries(void *obj)
773 {
774         ast_mutex_lock(&history_lock);
775         AST_VECTOR_RESET(&vector_history, clear_history_entry_cb);
776         packet_number = 0;
777         ast_mutex_unlock(&history_lock);
778
779         return 0;
780 }
781
782 /*!
783  * \brief Build a reverse polish notation expression queue
784  *
785  * This function is an implementation of the Shunting-Yard Algorithm. It takes
786  * a user provided infix-notation expression and converts it into a reverse
787  * polish notation expression, which is a queue of tokens that can be easily
788  * parsed.
789  *
790  * \params a The CLI arguments provided by the User, containing the infix expression
791  *
792  * \retval NULL error
793  * \retval expression_token A 'queue' of expression tokens in RPN
794  */
795 static struct expression_token *build_expression_queue(struct ast_cli_args *a)
796 {
797         AST_VECTOR(, struct operator *) operators; /* A stack of saved operators */
798         struct expression_token *output = NULL;    /* The output queue */
799         struct expression_token *head = NULL;      /* Pointer to the head of /c output */
800         int i;
801
802 #define APPEND_TO_OUTPUT(output, token) do { \
803         if ((output)) { \
804                 (output)->next = (token); \
805                 (output) = (token); \
806         } else { \
807                 (output) = (token); \
808                 head = (output); \
809         } \
810 } while (0)
811
812         if (AST_VECTOR_INIT(&operators, 8)) {
813                 return NULL;
814         }
815
816         for (i = 4; i < a->argc; i++) {
817                 struct expression_token *out_token;
818                 char *token = ast_strdupa(a->argv[i]);
819                 int j;
820
821                 /* Strip off and append any left parentheses */
822                 if (token[0] == '(') {
823                         AST_VECTOR_APPEND(&operators, &left_paren);
824                         if (!token[1]) {
825                                 continue;
826                         }
827                         token = &token[1];
828                 }
829
830                 /* Handle the case where the token is an operator */
831                 for (j = 0; j < ARRAY_LEN(allowed_operators); j++) {
832                         int k;
833
834                         if (strcasecmp(token, allowed_operators[j].symbol)) {
835                                 continue;
836                         }
837
838                         for (k = AST_VECTOR_SIZE(&operators) - 1; k >= 0; k--) {
839                                 struct operator *top = AST_VECTOR_GET(&operators, k);
840
841                                 /* Remove and push queued up operators, if they are of
842                                  * less precedence than this operator
843                                  */
844                                 if ((allowed_operators[j].right_to_left && allowed_operators[j].precedence >= top->precedence)
845                                         || (!allowed_operators[j].right_to_left && allowed_operators[j].precedence > top->precedence)) {
846
847                                         if (!(out_token = expression_token_alloc(TOKEN_TYPE_OPERATOR, top))) {
848                                                 goto error;
849                                         }
850                                         APPEND_TO_OUTPUT(output, out_token);
851                                         AST_VECTOR_REMOVE(&operators, k, 1);
852                                 }
853                         }
854
855                         AST_VECTOR_APPEND(&operators, &allowed_operators[j]);
856                         token = NULL;
857                         break;
858                 }
859
860                 /* Token was an operator; continue to next token */
861                 if (!token) {
862                         continue;
863                 }
864
865                 /* Handle a right parentheses either by itself or as part of the token.
866                  * If part of the token, push the token onto the output queue first
867                  */
868                 if (token[0] == ')' || token[strlen(token) - 1] == ')') {
869
870                         if (token[strlen(token) - 1] == ')') {
871                                 token[strlen(token) - 1] = '\0';
872
873                                 if (!(out_token = expression_token_alloc(TOKEN_TYPE_FIELD, token))) {
874                                         goto error;
875                                 }
876                                 APPEND_TO_OUTPUT(output, out_token);
877                                 token = NULL;
878                         }
879
880                         for (j = AST_VECTOR_SIZE(&operators) - 1; j >= 0; j--) {
881                                 struct operator *top = AST_VECTOR_GET(&operators, j);
882
883                                 AST_VECTOR_REMOVE(&operators, j, 1);
884                                 if (top == &left_paren) {
885                                         break;
886                                 }
887
888                                 if (!(out_token = expression_token_alloc(TOKEN_TYPE_OPERATOR, top))) {
889                                         goto error;
890                                 }
891                                 APPEND_TO_OUTPUT(output, out_token);
892                         }
893                 }
894
895                 /* Just a plain token, push to the output queue */
896                 if (token) {
897                         if (!(out_token = expression_token_alloc(TOKEN_TYPE_FIELD, token))) {
898                                 goto error;
899                         }
900                         APPEND_TO_OUTPUT(output, out_token);
901                 }
902         }
903
904         /* Remove any non-applied operators that remain, applying them
905          * to the output queue
906          */
907         for (i = AST_VECTOR_SIZE(&operators) - 1; i >= 0; i--) {
908                 struct operator *top = AST_VECTOR_GET(&operators, i);
909                 struct expression_token *out_token;
910
911                 AST_VECTOR_REMOVE(&operators, i, 1);
912                 if (top == &left_paren) {
913                         ast_log(LOG_WARNING, "Unbalanced '(' parentheses in expression!\n");
914                         continue;
915                 }
916
917                 if (!(out_token = expression_token_alloc(TOKEN_TYPE_OPERATOR, top))) {
918                         goto error;
919                 }
920                 APPEND_TO_OUTPUT(output, out_token);
921         }
922
923         AST_VECTOR_FREE(&operators);
924         return head;
925
926 error:
927         AST_VECTOR_FREE(&operators);
928         expression_token_free(output);
929         return NULL;
930 }
931
932 /*!
933  * \brief Evaluate a single entry in this history using a RPN expression
934  *
935  * \param entry The entry in the history to evaluate
936  * \param queue The RPN expression
937  *
938  * \retval 0 The expression evaluated FALSE on \c entry
939  * \retval 1 The expression evaluated TRUE on \c entry
940  * \retval -1 The expression errored
941  */
942 static int evaluate_history_entry(struct pjsip_history_entry *entry, struct expression_token *queue)
943 {
944         AST_VECTOR(, struct expression_token *) stack; /* Our stack of results and operands */
945         struct expression_token *it_queue;
946         struct expression_token *final;
947         int result;
948         int i;
949
950         if (AST_VECTOR_INIT(&stack, 16)) {
951                 return -1;
952         }
953
954         for (it_queue = queue; it_queue; it_queue = it_queue->next) {
955                 struct expression_token *op_one;
956                 struct expression_token *op_two = NULL;
957                 struct expression_token *result;
958                 int res = 0;
959
960                 /* If this is not an operator, push it to the stack */
961                 if (!it_queue->op) {
962                         AST_VECTOR_APPEND(&stack, it_queue);
963                         continue;
964                 }
965
966                 if (AST_VECTOR_SIZE(&stack) < it_queue->op->operands) {
967                         ast_log(LOG_WARNING, "Unable to evaluate expression operator '%s': not enough operands\n",
968                                 it_queue->op->symbol);
969                         goto error;
970                 }
971
972                 if (it_queue->op->operands == 1) {
973                         /* Unary operators currently consist only of 'not', which can only act
974                          * upon an evaluated condition result.
975                          */
976                         ast_assert(it_queue->op->evaluate_unary != NULL);
977
978                         op_one = AST_VECTOR_REMOVE(&stack, AST_VECTOR_SIZE(&stack) - 1, 1);
979                         if (op_one->token_type != TOKEN_TYPE_RESULT) {
980                                 ast_log(LOG_WARNING, "Unable to evaluate '%s': operand is not the result of an operation\n",
981                                         it_queue->op->symbol);
982                                 goto error;
983                         }
984
985                         res = it_queue->op->evaluate_unary(it_queue->op, OPT_INT_T, &op_one->result) == 0 ? 0 : 1;
986                 } else if (it_queue->op->operands == 2) {
987                         struct allowed_field *field;
988                         enum aco_option_type type;
989                         void *value;
990
991                         ast_assert(it_queue->op->evaluate != NULL);
992
993                         op_one = AST_VECTOR_REMOVE(&stack, AST_VECTOR_SIZE(&stack) - 1, 1);
994                         op_two = AST_VECTOR_REMOVE(&stack, AST_VECTOR_SIZE(&stack) - 1, 1);
995
996                         /* If operand two is a field, then it must be a field we recognize. */
997                         if (op_two->token_type == TOKEN_TYPE_FIELD) {
998                                 field = get_allowed_field(op_two);
999                                 if (!field) {
1000                                         ast_log(LOG_WARNING, "Unknown or unrecognized field: %s\n", op_two->field);
1001                                         goto error;
1002                                 }
1003
1004                                 type = field->return_type;
1005                                 value = field->get_field(entry);
1006                         } else if (op_two->token_type == TOKEN_TYPE_RESULT) {
1007                                 type = OPT_INT_T;
1008                                 value = &op_two->result;
1009                         } else {
1010                                 ast_log(LOG_WARNING, "Attempting to evaluate an operator: %s\n", op_two->op->symbol);
1011                                 goto error;
1012                         }
1013
1014                         if (value) {
1015                                 res = it_queue->op->evaluate(it_queue->op, type, value, op_one) == 0 ? 0 : 1;
1016                         } else {
1017                                 res = 0;
1018                         }
1019                 } else {
1020                         ast_log(LOG_WARNING, "Operator '%s' has an invalid number of operands\n", it_queue->op->symbol);
1021                         ast_assert(0);
1022                         goto error;
1023                 }
1024
1025                 /* Results are temporary; clean used ones up */
1026                 if (op_one && op_one->token_type == TOKEN_TYPE_RESULT) {
1027                         ast_free(op_one);
1028                 }
1029                 if (op_two && op_two->token_type == TOKEN_TYPE_RESULT) {
1030                         ast_free(op_two);
1031                 }
1032
1033                 /* Push the result onto the stack */
1034                 result = expression_token_alloc(TOKEN_TYPE_RESULT, &res);
1035                 if (!result) {
1036                         goto error;
1037                 }
1038                 AST_VECTOR_APPEND(&stack, result);
1039         }
1040
1041         /*
1042          * When the evaluation is complete, we must have:
1043          *  - A single result remaining on the stack
1044          *  - An actual result
1045          */
1046         if (AST_VECTOR_SIZE(&stack) != 1) {
1047                 ast_log(LOG_WARNING, "Expression was unbalanced: %zu results remained after evaluation\n",
1048                         AST_VECTOR_SIZE(&stack));
1049                 goto error;
1050         }
1051
1052         final = AST_VECTOR_GET(&stack, 0);
1053         if (final->token_type != TOKEN_TYPE_RESULT) {
1054                 ast_log(LOG_WARNING, "Expression did not create a usable result\n");
1055                 goto error;
1056         }
1057         result = final->result;
1058         ast_free(final);
1059
1060         return result;
1061
1062 error:
1063         /* Clean out any remaining result expression tokens */
1064         for (i = 0; i < AST_VECTOR_SIZE(&stack); i++) {
1065                 struct expression_token *failed_token = AST_VECTOR_GET(&stack, i);
1066
1067                 if (failed_token->token_type == TOKEN_TYPE_RESULT) {
1068                         ast_free(failed_token);
1069                 }
1070         }
1071         AST_VECTOR_FREE(&stack);
1072         return -1;
1073 }
1074
1075 /*!
1076  * \brief Create a filtered history based on a user provided expression
1077  *
1078  * \param a The CLI arguments containing the expression
1079  *
1080  * \retval NULL on error
1081  * \retval A vector containing the filtered history on success
1082  */
1083 static struct vector_history_t *filter_history(struct ast_cli_args *a)
1084 {
1085         struct vector_history_t *output;
1086         struct expression_token *queue;
1087         int i;
1088
1089         output = ast_malloc(sizeof(*output));
1090         if (!output) {
1091                 return NULL;
1092         }
1093
1094         if (AST_VECTOR_INIT(output, HISTORY_INITIAL_SIZE / 2)) {
1095                 ast_free(output);
1096                 return NULL;
1097         }
1098
1099         queue = build_expression_queue(a);
1100         if (!queue) {
1101                 return NULL;
1102         }
1103
1104         ast_mutex_lock(&history_lock);
1105         for (i = 0; i < AST_VECTOR_SIZE(&vector_history); i++) {
1106                 struct pjsip_history_entry *entry = AST_VECTOR_GET(&vector_history, i);
1107                 int res;
1108
1109                 res = evaluate_history_entry(entry, queue);
1110                 if (res == -1) {
1111                         /* Error in expression evaluation; bail */
1112                         ast_mutex_unlock(&history_lock);
1113                         AST_VECTOR_RESET(output, clear_history_entry_cb);
1114                         AST_VECTOR_FREE(output);
1115                         ast_free(output);
1116                         expression_token_free(queue);
1117                         return NULL;
1118                 } else if (!res) {
1119                         continue;
1120                 } else {
1121                         AST_VECTOR_APPEND(output, ao2_bump(entry));
1122                 }
1123         }
1124         ast_mutex_unlock(&history_lock);
1125
1126         expression_token_free(queue);
1127
1128         return output;
1129 }
1130
1131 /*! \brief Print a detailed view of a single entry in the history to the CLI */
1132 static void display_single_entry(struct ast_cli_args *a, struct pjsip_history_entry *entry)
1133 {
1134         char addr[64];
1135         char *buf;
1136
1137         buf = ast_calloc(1, PJSIP_MAX_PKT_LEN * sizeof(char));
1138         if (!buf) {
1139                 return;
1140         }
1141
1142         if (pjsip_msg_print(entry->msg, buf, PJSIP_MAX_PKT_LEN) == -1) {
1143                 ast_log(LOG_WARNING, "Unable to print SIP message %d: packet too large!\n", entry->number);
1144                 ast_free(buf);
1145                 return;
1146         }
1147
1148         if (entry->transmitted) {
1149                 pj_sockaddr_print(&entry->dst, addr, sizeof(addr), 3);
1150         } else {
1151                 pj_sockaddr_print(&entry->src, addr, sizeof(addr), 3);
1152         }
1153
1154         ast_cli(a->fd, "<--- History Entry %d %s %s at %-10.10ld --->\n",
1155                 entry->number,
1156                 entry->transmitted ? "Sent to" : "Received from",
1157                 addr,
1158                 entry->timestamp.tv_sec);
1159         ast_cli(a->fd, "%s\n", buf);
1160
1161         ast_free(buf);
1162 }
1163
1164 /*! \brief Print a list of the entries to the CLI */
1165 static void display_entry_list(struct ast_cli_args *a, struct vector_history_t *vec)
1166 {
1167         int i;
1168
1169         ast_cli(a->fd, "%-5.5s %-10.10s %-30.30s %-35.35s\n",
1170                 "No.",
1171                 "Timestamp",
1172                 "(Dir) Address",
1173                 "SIP Message");
1174         ast_cli(a->fd, "===== ========== ============================== ===================================\n");
1175
1176         for (i = 0; i < AST_VECTOR_SIZE(vec); i++) {
1177                 struct pjsip_history_entry *entry;
1178                 char line[256];
1179
1180                 entry = AST_VECTOR_GET(vec, i);
1181                 sprint_list_entry(entry, line, sizeof(line));
1182
1183                 ast_cli(a->fd, "%s\n", line);
1184         }
1185 }
1186
1187 /*! \brief Cleanup routine for a history vector, serviced on a registered PJSIP thread */
1188 static int safe_vector_cleanup(void *obj)
1189 {
1190         struct vector_history_t *vec = obj;
1191
1192         AST_VECTOR_RESET(vec, clear_history_entry_cb);
1193         AST_VECTOR_FREE(vec);
1194         ast_free(vec);
1195
1196         return 0;
1197 }
1198
1199 static char *pjsip_show_history(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1200 {
1201         struct vector_history_t *vec = &vector_history;
1202         struct pjsip_history_entry *entry = NULL;
1203
1204         if (cmd == CLI_INIT) {
1205                 e->command = "pjsip show history";
1206                 e->usage =
1207                         "Usage: pjsip show history [entry <num>|where [...]]\n"
1208                         "       Displays the currently collected history or an\n"
1209                         "       entry within the history.\n\n"
1210                         "       * Running the command with no options will display\n"
1211                         "         the entire history.\n"
1212                         "       * Providing 'entry <num>' will display the full\n"
1213                         "         detail of a particular entry in this history.\n"
1214                         "       * Providing 'where ...' will allow for filtering\n"
1215                         "         the history. The history can be filtered using\n"
1216                         "         any of the following fields:\n"
1217                         "         - number: The history entry number\n"
1218                         "         - timestamp: The time associated with the history entry\n"
1219                         "         - addr: The source/destination address of the SIP message\n"
1220                         "         - sip.msg.request.method: The request method type\n"
1221                         "         - sip.msg.call-id: The Call-ID header of the SIP message\n"
1222                         "\n"
1223                         "         When filtering, standard Boolean operators can be used,\n"
1224                         "         as well as 'like' for regexs.\n"
1225                         "\n"
1226                         "         Example:\n"
1227                         "         'pjsip show history where number > 5 and (addr = \"192.168.0.3:5060\" or addr = \"192.168.0.5:5060\")'\n";
1228                 return NULL;
1229         } else if (cmd == CLI_GENERATE) {
1230                 return NULL;
1231         }
1232
1233         if (a->argc > 3) {
1234                 if (!strcasecmp(a->argv[3], "entry") && a->argc == 5) {
1235                         int num;
1236
1237                         if (sscanf(a->argv[4], "%30d", &num) != 1) {
1238                                 ast_cli(a->fd, "'%s' is not a valid entry number\n", a->argv[4]);
1239                                 return CLI_FAILURE;
1240                         }
1241
1242                         /* Get the entry at the provided position */
1243                         ast_mutex_lock(&history_lock);
1244                         if (num >= AST_VECTOR_SIZE(&vector_history) || num < 0) {
1245                                 ast_cli(a->fd, "Entry '%d' does not exist\n", num);
1246                                 ast_mutex_unlock(&history_lock);
1247                                 return CLI_FAILURE;
1248                         }
1249                         entry = ao2_bump(AST_VECTOR_GET(&vector_history, num));
1250                         ast_mutex_unlock(&history_lock);
1251                 } else if (!strcasecmp(a->argv[3], "where")) {
1252                         vec = filter_history(a);
1253                         if (!vec) {
1254                                 return CLI_FAILURE;
1255                         }
1256                 } else {
1257                         return CLI_SHOWUSAGE;
1258                 }
1259         }
1260
1261         if (AST_VECTOR_SIZE(vec) == 1) {
1262                 if (vec == &vector_history) {
1263                         ast_mutex_lock(&history_lock);
1264                 }
1265                 entry = ao2_bump(AST_VECTOR_GET(vec, 0));
1266                 if (vec == &vector_history) {
1267                         ast_mutex_lock(&history_lock);
1268                 }
1269         }
1270
1271         if (entry) {
1272                 display_single_entry(a, entry);
1273         } else {
1274                 if (vec == &vector_history) {
1275                         ast_mutex_lock(&history_lock);
1276                 }
1277
1278                 display_entry_list(a, vec);
1279
1280                 if (vec == &vector_history) {
1281                         ast_mutex_unlock(&history_lock);
1282                 }
1283         }
1284
1285         if (vec != &vector_history) {
1286                 ast_sip_push_task(NULL, safe_vector_cleanup, vec);
1287         }
1288         ao2_cleanup(entry);
1289
1290         return CLI_SUCCESS;
1291 }
1292
1293 static char *pjsip_set_history(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1294 {
1295         const char *what;
1296
1297         if (cmd == CLI_INIT) {
1298                 e->command = "pjsip set history {on|off|clear}";
1299                 e->usage =
1300                         "Usage: pjsip set history {on|off|clear}\n"
1301                         "       Enables/disables/clears the PJSIP history.\n\n"
1302                         "       Enabling the history will start recording transmitted/received\n"
1303                         "       packets. Disabling the history will stop recording, but keep\n"
1304                         "       the already received packets. Clearing the history will wipe\n"
1305                         "       the received packets from memory.\n\n"
1306                         "       As the PJSIP history is maintained in memory, and includes\n"
1307                         "       all received/transmitted requests and responses, it should\n"
1308                         "       only be enabled for debugging purposes, and cleared when done.\n";
1309                 return NULL;
1310         } else if (cmd == CLI_GENERATE) {
1311                 return NULL;
1312         }
1313
1314         what = a->argv[e->args - 1];    /* Guaranteed to exist */
1315
1316         if (a->argc == e->args) {
1317                 if (!strcasecmp(what, "on")) {
1318                         enabled = 1;
1319                         ast_cli(a->fd, "PJSIP History enabled\n");
1320                         return CLI_SUCCESS;
1321                 } else if (!strcasecmp(what, "off")) {
1322                         enabled = 0;
1323                         ast_cli(a->fd, "PJSIP History disabled\n");
1324                         return CLI_SUCCESS;
1325                 } else if (!strcasecmp(what, "clear")) {
1326                         ast_sip_push_task(NULL, clear_history_entries, NULL);
1327                         ast_cli(a->fd, "PJSIP History cleared\n");
1328                         return CLI_SUCCESS;
1329                 }
1330         }
1331
1332         return CLI_SHOWUSAGE;
1333 }
1334
1335 static pjsip_module logging_module = {
1336         .name = { "History Module", 14 },
1337         .priority = 0,
1338         .on_rx_request = history_on_rx_msg,
1339         .on_rx_response = history_on_rx_msg,
1340         .on_tx_request = history_on_tx_msg,
1341         .on_tx_response = history_on_tx_msg,
1342 };
1343
1344 static struct ast_cli_entry cli_pjsip[] = {
1345         AST_CLI_DEFINE(pjsip_set_history, "Enable/Disable PJSIP History"),
1346         AST_CLI_DEFINE(pjsip_show_history, "Display PJSIP History"),
1347 };
1348
1349 static int load_module(void)
1350 {
1351         CHECK_PJSIP_MODULE_LOADED();
1352
1353         log_level = ast_logger_register_level("PJSIP_HISTORY");
1354         if (log_level < 0) {
1355                 ast_log(LOG_WARNING, "Unable to register history log level\n");
1356         }
1357
1358         pj_caching_pool_init(&cachingpool, &pj_pool_factory_default_policy, 0);
1359
1360         AST_VECTOR_INIT(&vector_history, HISTORY_INITIAL_SIZE);
1361
1362         ast_sip_register_service(&logging_module);
1363         ast_cli_register_multiple(cli_pjsip, ARRAY_LEN(cli_pjsip));
1364
1365         return AST_MODULE_LOAD_SUCCESS;
1366 }
1367
1368 static int unload_module(void)
1369 {
1370         ast_cli_unregister_multiple(cli_pjsip, ARRAY_LEN(cli_pjsip));
1371         ast_sip_unregister_service(&logging_module);
1372
1373         ast_sip_push_task_synchronous(NULL, clear_history_entries, NULL);
1374         AST_VECTOR_FREE(&vector_history);
1375
1376         pj_caching_pool_destroy(&cachingpool);
1377
1378         if (log_level != -1) {
1379                 ast_logger_unregister_level("PJSIP_HISTORY");
1380         }
1381
1382         return 0;
1383 }
1384
1385 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP History",
1386                 .support_level = AST_MODULE_SUPPORT_EXTENDED,
1387                 .load = load_module,
1388                 .unload = unload_module,
1389                 .load_pri = AST_MODPRI_APP_DEPEND,
1390         );