res_pjsip_history.c 38 KB

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