res_hep/res_hep_pjsip: Add a HEPv3 capture agent module and a logger for PJSIP
[asterisk/asterisk.git] / res / res_hep_pjsip.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2014, 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 logging with Homer
22  *
23  * \author Matt Jordan <mjordan@digium.com>
24  *
25  */
26
27 /*** MODULEINFO
28         <depend>pjproject</depend>
29         <depend>res_pjsip</depend>
30         <depend>res_hep</depend>
31         <defaultenabled>no</defaultenabled>
32         <support_level>extended</support_level>
33  ***/
34
35 #include "asterisk.h"
36
37 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
38
39 #include <pjsip.h>
40
41 #include "asterisk/res_pjsip.h"
42 #include "asterisk/res_hep.h"
43 #include "asterisk/module.h"
44 #include "asterisk/netsock2.h"
45
46 static pj_status_t logging_on_tx_msg(pjsip_tx_data *tdata)
47 {
48         char local_buf[256];
49         char remote_buf[256];
50         char *uuid;
51         struct hepv3_capture_info *capture_info;
52         pjsip_cid_hdr *cid_hdr;
53
54         capture_info = hepv3_create_capture_info(tdata->buf.start, (size_t)(tdata->buf.cur - tdata->buf.start));
55         if (!capture_info) {
56                 return PJ_SUCCESS;
57         }
58
59         pj_sockaddr_print(&tdata->tp_info.transport->local_addr, local_buf, sizeof(local_buf), 3);
60         pj_sockaddr_print(&tdata->tp_info.dst_addr, remote_buf, sizeof(remote_buf), 3);
61
62         cid_hdr = PJSIP_MSG_CID_HDR(tdata->msg);
63         uuid = ast_malloc(pj_strlen(&cid_hdr->id) + 1);
64         if (!uuid) {
65                 ao2_ref(capture_info, -1);
66                 return PJ_SUCCESS;
67         }
68         ast_copy_pj_str(uuid, &cid_hdr->id, pj_strlen(&cid_hdr->id) + 1);
69
70         ast_sockaddr_parse(&capture_info->src_addr, local_buf, PARSE_PORT_REQUIRE);
71         ast_sockaddr_parse(&capture_info->dst_addr, remote_buf, PARSE_PORT_REQUIRE);
72
73         capture_info->capture_time = ast_tvnow();
74         capture_info->capture_type = HEPV3_CAPTURE_TYPE_SIP;
75         capture_info->uuid = uuid;
76         capture_info->zipped = 0;
77
78         hepv3_send_packet(capture_info);
79
80         return PJ_SUCCESS;
81 }
82
83 static pj_bool_t logging_on_rx_msg(pjsip_rx_data *rdata)
84 {
85         char local_buf[256];
86         char remote_buf[256];
87         char *uuid;
88         struct hepv3_capture_info *capture_info;
89
90         capture_info = hepv3_create_capture_info(&rdata->pkt_info.packet, rdata->pkt_info.len);
91         if (!capture_info) {
92                 return PJ_SUCCESS;
93         }
94
95         pj_sockaddr_print(&rdata->tp_info.transport->local_addr, local_buf, sizeof(local_buf), 3);
96         pj_sockaddr_print(&rdata->pkt_info.src_addr, remote_buf, sizeof(remote_buf), 3);
97
98         uuid = ast_malloc(pj_strlen(&rdata->msg_info.cid->id) + 1);
99         if (!uuid) {
100                 ao2_ref(capture_info, -1);
101                 return PJ_SUCCESS;
102         }
103         ast_copy_pj_str(uuid, &rdata->msg_info.cid->id, pj_strlen(&rdata->msg_info.cid->id) + 1);
104
105         ast_sockaddr_parse(&capture_info->src_addr, remote_buf, PARSE_PORT_REQUIRE);
106         ast_sockaddr_parse(&capture_info->dst_addr, local_buf, PARSE_PORT_REQUIRE);
107         capture_info->capture_time.tv_sec = rdata->pkt_info.timestamp.sec;
108         capture_info->capture_time.tv_usec = rdata->pkt_info.timestamp.msec * 1000;
109         capture_info->capture_type = HEPV3_CAPTURE_TYPE_SIP;
110         capture_info->uuid = uuid;
111         capture_info->zipped = 0;
112
113         hepv3_send_packet(capture_info);
114
115         return PJ_FALSE;
116 }
117
118 static pjsip_module logging_module = {
119         .name = { "HEPv3 Logging Module", 20 },
120         .priority = 0,
121         .on_rx_request = logging_on_rx_msg,
122         .on_rx_response = logging_on_rx_msg,
123         .on_tx_request = logging_on_tx_msg,
124         .on_tx_response = logging_on_tx_msg,
125 };
126
127
128 static int load_module(void)
129 {
130         ast_sip_register_service(&logging_module);
131         return AST_MODULE_LOAD_SUCCESS;
132 }
133
134 static int unload_module(void)
135 {
136         ast_sip_unregister_service(&logging_module);
137         return 0;
138 }
139
140 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP HEPv3 Logger",
141                 .load = load_module,
142                 .unload = unload_module,
143                 .load_pri = AST_MODPRI_DEFAULT,
144                );