Asterisk - The Open Source Telephony Project  18.5.0
res_hep_rtcp.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2014, Digium, Inc.
5  *
6  * Matt Jordan <[email protected]>
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 RTCP logging with Homer
22  *
23  * \author Matt Jordan <[email protected]>
24  *
25  */
26 
27 /*** MODULEINFO
28  <depend>res_hep</depend>
29  <support_level>extended</support_level>
30  ***/
31 
32 #include "asterisk.h"
33 
34 #include "asterisk/res_hep.h"
35 #include "asterisk/module.h"
36 #include "asterisk/netsock2.h"
37 #include "asterisk/channel.h"
38 #include "asterisk/pbx.h"
39 #include "asterisk/stasis.h"
40 #include "asterisk/rtp_engine.h"
41 #include "asterisk/json.h"
42 #include "asterisk/config.h"
43 
45 
46 static char *assign_uuid(struct ast_json *json_channel)
47 {
48  const char *channel_name = ast_json_string_get(ast_json_object_get(json_channel, "name"));
49  enum hep_uuid_type uuid_type = hepv3_get_uuid_type();
50  char *uuid = NULL;
51 
52  if (!channel_name) {
53  return NULL;
54  }
55 
56  if (uuid_type == HEP_UUID_TYPE_CALL_ID) {
57  struct ast_channel *chan = NULL;
58  char buf[128];
59 
60  if (ast_begins_with(channel_name, "PJSIP")) {
61  chan = ast_channel_get_by_name(channel_name);
62 
63  if (chan && !ast_func_read(chan, "CHANNEL(pjsip,call-id)", buf, sizeof(buf))) {
64  uuid = ast_strdup(buf);
65  }
66  } else if (ast_begins_with(channel_name, "SIP")) {
67  chan = ast_channel_get_by_name(channel_name);
68 
69  if (chan && !ast_func_read(chan, "SIP_HEADER(call-id)", buf, sizeof(buf))) {
70  uuid = ast_strdup(buf);
71  }
72  }
73 
74  ast_channel_cleanup(chan);
75  }
76 
77  /* If we couldn't get the call-id or didn't want it, just use the channel name */
78  if (!uuid) {
79  uuid = ast_strdup(channel_name);
80  }
81 
82  return uuid;
83 }
84 
86 {
87 
88  RAII_VAR(struct ast_json *, json_payload, NULL, ast_json_unref);
89  RAII_VAR(char *, payload, NULL, ast_json_free);
90  struct ast_json *json_blob;
91  struct ast_json *json_channel;
92  struct ast_json *json_rtcp;
93  struct hepv3_capture_info *capture_info;
94  struct ast_json *from;
95  struct ast_json *to;
96  struct timeval current_time = ast_tvnow();
97 
98  json_payload = stasis_message_to_json(message, NULL);
99  if (!json_payload) {
100  return;
101  }
102 
103  json_blob = ast_json_object_get(json_payload, "blob");
104  if (!json_blob) {
105  return;
106  }
107 
108  json_channel = ast_json_object_get(json_payload, "channel");
109  if (!json_channel) {
110  return;
111  }
112 
113  json_rtcp = ast_json_object_get(json_payload, "rtcp_report");
114  if (!json_rtcp) {
115  return;
116  }
117 
118  from = ast_json_object_get(json_blob, "from");
119  to = ast_json_object_get(json_blob, "to");
120  if (!from || !to) {
121  return;
122  }
123 
124  payload = ast_json_dump_string(json_rtcp);
125  if (ast_strlen_zero(payload)) {
126  return;
127  }
128 
129  capture_info = hepv3_create_capture_info(payload, strlen(payload));
130  if (!capture_info) {
131  return;
132  }
135 
136  capture_info->uuid = assign_uuid(json_channel);
137  if (!capture_info->uuid) {
138  ao2_ref(capture_info, -1);
139  return;
140  }
141  capture_info->capture_time = current_time;
142  capture_info->capture_type = HEPV3_CAPTURE_TYPE_RTCP;
143  capture_info->zipped = 0;
144 
145  hepv3_send_packet(capture_info);
146 }
147 
148 static void rtp_topic_handler(void *data, struct stasis_subscription *sub, struct stasis_message *message)
149 {
150  struct stasis_message_type *message_type = stasis_message_type(message);
151 
152  if ((message_type == ast_rtp_rtcp_sent_type()) ||
153  (message_type == ast_rtp_rtcp_received_type())) {
154  rtcp_message_handler(message);
155  }
156 }
157 
158 static int load_module(void)
159 {
160  if (!hepv3_is_loaded()) {
161  ast_log(AST_LOG_WARNING, "res_hep is disabled; declining module load\n");
163  }
164 
165  stasis_rtp_subscription = stasis_subscribe(ast_rtp_topic(),
167  if (!stasis_rtp_subscription) {
169  }
173 
175 }
176 
177 static int unload_module(void)
178 {
179  if (stasis_rtp_subscription) {
180  stasis_rtp_subscription = stasis_unsubscribe_and_join(stasis_rtp_subscription);
181  }
182 
183  return 0;
184 }
185 
187  .support_level = AST_MODULE_SUPPORT_EXTENDED,
188  .load = load_module,
189  .unload = unload_module,
190  .requires = "res_hep",
191 );
struct stasis_message_type * ast_rtp_rtcp_sent_type(void)
Message type for an RTCP message sent from this Asterisk instance.
struct ast_sockaddr src_addr
Definition: res_hep.h:60
int ast_func_read(struct ast_channel *chan, const char *function, char *workspace, size_t len)
executes a read operation on a function
Main Channel structure associated with a channel.
Asterisk main include file. File version handling, generic pbx functions.
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
enum hepv3_capture_type capture_type
Definition: res_hep.h:70
void ast_json_free(void *p)
Asterisk&#39;s custom JSON allocator. Exposed for use by unit tests.
Definition: json.c:52
struct ast_sockaddr dst_addr
Definition: res_hep.h:62
#define AST_LOG_WARNING
Definition: logger.h:279
Routines for integration with Homer using HEPv3.
#define ast_json_dump_string(root)
Encode a JSON value to a compact string.
Definition: json.h:763
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
Definition: stasis.c:1079
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
static struct stasis_subscription * stasis_rtp_subscription
Definition: res_hep_rtcp.c:44
struct stasis_message_type * ast_rtp_rtcp_received_type(void)
Message type for an RTCP message received from some external source.
struct ast_json * stasis_message_to_json(struct stasis_message *msg, struct stasis_message_sanitizer *sanitize)
Build the JSON representation of the message.
unsigned int zipped
Definition: res_hep.h:74
#define ast_strlen_zero(foo)
Definition: strings.h:52
HEPv3 Capture Info.
Definition: res_hep.h:58
Configuration File Parser.
#define ast_log
Definition: astobj2.c:42
General Asterisk PBX channel definitions.
Asterisk JSON abstraction layer.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2992
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static char * assign_uuid(struct ast_json *json_channel)
Definition: res_hep_rtcp.c:46
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:273
static void rtcp_message_handler(struct stasis_message *message)
Definition: res_hep_rtcp.c:85
Network socket handling.
Core PBX routines and definitions.
#define stasis_subscribe(topic, callback, data)
Definition: stasis.h:652
struct hepv3_capture_info * hepv3_create_capture_info(const void *payload, size_t len)
Create a hepv3_capture_info object.
Definition: res_hep.c:428
enum hep_uuid_type hepv3_get_uuid_type(void)
Get the preferred UUID type.
Definition: res_hep.c:409
static int unload_module(void)
Definition: res_hep_rtcp.c:177
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
Definition: stasis.c:1136
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
hep_uuid_type
Definition: res_hep.h:52
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
int hepv3_is_loaded(void)
Return whether or not we&#39;re currently loaded and active.
Definition: res_hep.c:421
struct timeval capture_time
Definition: res_hep.h:64
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:397
static void rtp_topic_handler(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: res_hep_rtcp.c:148
struct stasis_topic * ast_rtp_topic(void)
Stasis Message Bus API topic for RTP and RTCP related messages
Definition: rtp_engine.c:3531
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
Definition: stasis.c:1025
struct stasis_forward * sub
Definition: res_corosync.c:240
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Definition: strings.h:94
Abstract JSON element (object, array, string, int, ...).
int hepv3_send_packet(struct hepv3_capture_info *capture_info)
Send a generic packet capture to HEPv3.
Definition: res_hep.c:581
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454
Pluggable RTP Architecture.
Asterisk module definitions.
static int load_module(void)
Definition: res_hep_rtcp.c:158