246#define MAX_RTP_MIME_TYPES 128
287#define SET_AST_JSON_OBJ(target, name, obj) ({ \
288 struct ast_json *j_tmp = obj; \
290 ast_json_object_set(target, name, j_tmp); \
341 engine->
mod = module;
347 if (!strcmp(current_engine->
name, engine->
name)) {
359 ast_verb(5,
"Registered RTP engine '%s'\n", engine->
name);
371 ast_verb(5,
"Unregistered RTP engine '%s'\n", engine->
name);
376 return current_engine ? 0 : -1;
392 if (!strcasecmp(current_glue->
type, glue->
type)) {
415 ast_verb(5,
"Unregistered RTP glue '%s'\n", glue->
type);
420 return current_glue ? 0 : -1;
428 if (instance->
data) {
438 if (instance->
srtp) {
455 ast_debug(1,
"Destroyed RTP instance '%p'\n", instance);
472 buffer[0],
sizeof(buffer[0])),
474 buffer[1],
sizeof(buffer[1])),
476 buffer[2],
sizeof(buffer[2])),
478 buffer[3],
sizeof(buffer[3]))
501 if (!strcmp(engine->
name, engine_name)) {
531 instance->
engine = engine;
548 ast_debug(1,
"Using engine '%s' for RTP instance '%p'\n", engine->
name, instance);
558 ast_debug(1,
"Engine '%s' failed to setup RTP instance '%p'\n", engine->
name, instance);
565 ast_debug(1,
"RTP instance '%p' is setup and ready to go\n", instance);
582 instance->
data = data;
587 return instance->
data;
605 frame = instance->
engine->
read(instance, rtcp);
841 const char *uri,
const char *attributes)
886 static const struct rtp_extmap extmap_none = {
1106 "cleaning up rx mapping vector element about to be replaced");
1157 ast_debug(2,
"Copying rx payload mapping %d (%p) from %p to %p\n",
1158 idx,
type, src, dest);
1222 if (
codecs && to_match) {
1253 ast_debug(2,
"Copying tx payload mapping %d (%p) from %p to %p\n",
1254 idx,
type, src, dest);
1258 "cleaning up tx mapping vector element about to be replaced");
1334 ast_debug(2,
"Crossover copying tx to rx payload mapping %d (%p) from %p to %p\n",
1335 idx,
type, src, dest);
1368 ast_debug(1,
"Don't have a default tx payload type %d format for m type on %p\n",
1373 ast_debug(1,
"Setting tx payload type %d based on m type on %p\n",
1381 "cleaning up replaced tx payload type");
1399 char *mimetype,
char *mimesubtype,
1417 if (strcasecmp(mimesubtype, t->
subtype)) {
1421 if (strcasecmp(mimetype, t->
type)) {
1461 "cleaning up replaced tx payload type");
1481 return (found ? 0 : -2);
1538 if (
type &&
type->asterisk_format) {
1593 pt =
codecs->preferred_dtmf_pt;
1602 rate =
codecs->preferred_dtmf_rate;
1610 codecs->preferred_dtmf_pt = pt;
1611 codecs->preferred_dtmf_rate = rate;
1630 type->asterisk_format = 1;
1632 type->primary_mapping = 1;
1662 if (
type &&
type->asterisk_format) {
1678 codecs->framing = framing;
1684 unsigned int framing;
1687 framing =
codecs->framing;
1710 if (
type->asterisk_format) {
1713 *nonastformats |=
type->rtp_code;
1785 for (x = start; x <
end; ++x) {
1894 struct timeval oldest;
1902 && !
type->primary_mapping
1905 oldest =
type->when_retired;
1930 int payload = code, i;
1966 }
else if (
payload > -1 && !
explicit
1997 }
else if (
explicit) {
2039 if (!
type->asterisk_format
2040 &&
type->primary_mapping
2041 &&
type->rtp_code == code
2056 if (
type->asterisk_format
2057 &&
type->primary_mapping
2099 if (!
type->asterisk_format
2100 &&
type->rtp_code == code
2118 if (
type->asterisk_format
2172 const char *res =
"";
2202 unsigned int res = 0;
2244 if (rtp_capability & x) {
2374 res = instance->
engine->
fd(instance, rtcp);
2389 if (!strcasecmp(glue->
type,
type)) {
2430 *vinstance_dst =
NULL, *vinstance_src =
NULL,
2431 *tinstance_dst =
NULL, *tinstance_src =
NULL;
2441 if (!cap_src || !cap_dst) {
2451 audio_glue_dst_res = glue_dst->
get_rtp_info(c_dst, &instance_dst);
2454 audio_glue_src_res = glue_src->
get_rtp_info(c_src, &instance_src);
2483 if (vinstance_dst && vinstance_src) {
2486 if (tinstance_dst && tinstance_src) {
2490 if (glue_dst->
update_peer(c_dst, instance_src, vinstance_src, tinstance_src, cap_src, 0)) {
2494 ast_debug(1,
"Seeded SDP of '%s' with that of '%s'\n",
2516 *vinstance0 =
NULL, *vinstance1 =
NULL,
2517 *tinstance0 =
NULL, *tinstance1 =
NULL;
2525 if (!c1 || !cap1 || !cap0) {
2571 if (glue0->
update_peer(c0, instance1, vinstance1, tinstance1, cap1, 0)) {
2600 res = instance->
engine->
red_init(instance, buffer_time, payloads, generations);
2626 if (!instance || !instance->
engine || !stats) {
2667 snprintf(
buf, size,
"ssrc=%u;themssrc=%u;lp=%u;rxjitter=%f;rxcount=%u;"
2668 "txjitter=%f;txcount=%u;rlp=%u;rtt=%f;rxmes=%f;txmes=%f",
2673 snprintf(
buf, size,
"minrxjitter=%010.6f;maxrxjitter=%010.6f;avgrxjitter=%010.6f;stdevrxjitter=%010.6f;mintxjitter=%010.6f;maxtxjitter=%010.6f;avgtxjitter=%010.6f;stdevtxjitter=%010.6f;",
2676 snprintf(
buf, size,
" minrxlost=%010.6f; maxrxlost=%010.6f; avgrxlost=%010.6f; stdevrxlost=%010.6f; mintxlost=%010.6f; maxtxlost=%010.6f; avgtxlost=%010.6f; stdevtxlost=%010.6f;",
2681 snprintf(
buf, size,
" minrxmes=%010.6f; maxrxmes=%010.6f; avgrxmes=%010.6f; stdevrxmes=%010.6f; mintxmes=%010.6f; maxtxmes=%010.6f; avgtxmes=%010.6f; stdevtxmes=%010.6f;",
2707 quality_buf,
sizeof(quality_buf));
2807 if (!peer_instance) {
2828 peer_instance =
NULL;
2863 const char *username)
2907 return instance->
glue;
2951 }
else if (remote_policy) {
2968 return instance->
srtp;
3026 const char *password;
3041 return local_candidates;
3061 const char *server,
unsigned int port,
const char *username,
const char *password)
3065 username, password);
3100#ifdef TEST_FRAMEWORK
3101struct ast_rtp_engine_test *ast_rtp_instance_get_test(
struct ast_rtp_instance *instance)
3103 return instance->
engine->test;
3110 int set_configuration;
3115 return set_configuration;
3149 return get_connection;
3185 return get_fingerprint_hash;
3190 const char *get_fingerprint;
3195 return get_fingerprint;
3222 if (!strcasecmp(
name,
"dtlsenable")) {
3224 }
else if (!strcasecmp(
name,
"dtlsverify")) {
3225 if (!strcasecmp(
value,
"yes")) {
3227 }
else if (!strcasecmp(
value,
"fingerprint")) {
3229 }
else if (!strcasecmp(
value,
"certificate")) {
3231 }
else if (!strcasecmp(
value,
"no")) {
3236 }
else if (!strcasecmp(
name,
"dtlsrekey")) {
3237 if (sscanf(
value,
"%30u", &dtls_cfg->
rekey) != 1) {
3240 }
else if (!strcasecmp(
name,
"dtlsautogeneratecert")) {
3242 }
else if (!strcasecmp(
name,
"dtlscertfile")) {
3249 }
else if (!strcasecmp(
name,
"dtlsprivatekey")) {
3256 }
else if (!strcasecmp(
name,
"dtlscipher")) {
3259 }
else if (!strcasecmp(
name,
"dtlscafile")) {
3266 }
else if (!strcasecmp(
name,
"dtlscapath") || !strcasecmp(
name,
"dtlscadir")) {
3273 }
else if (!strcasecmp(
name,
"dtlssetup")) {
3274 if (!strcasecmp(
value,
"active")) {
3276 }
else if (!strcasecmp(
value,
"passive")) {
3278 }
else if (!strcasecmp(
value,
"actpass")) {
3281 }
else if (!strcasecmp(
name,
"dtlsfingerprint")) {
3282 if (!strcasecmp(
value,
"sha-256")) {
3284 }
else if (!strcasecmp(
value,
"sha-1")) {
3298 ast_log(
LOG_ERROR,
"You cannot request automatically generated certificates"
3299 " (dtls_auto_generate_cert) and also specify a certificate file"
3300 " (dtls_cert_file) at the same time\n");
3306 " ignored when dtls_auto_generate_cert is enabled\n");
3507 if (!packet_string) {
3513 if (!channel_string) {
3518 if (payload->
blob) {
3540 ast_str_append(&packet_string, 0,
"ReportCount: %u\r\n", report_count);
3553 for (i = 0; i < report_count; i++) {
3561 if (!report_string) {
3565 ast_str_append(&report_string, 0,
"Report%dSourceSSRC: 0x%.8x\r\n",
3567 ast_str_append(&report_string, 0,
"Report%dFractionLost: %d\r\n",
3569 ast_str_append(&report_string, 0,
"Report%dCumulativeLost: %u\r\n",
3571 ast_str_append(&report_string, 0,
"Report%dHighestSequence: %u\r\n",
3573 ast_str_append(&report_string, 0,
"Report%dSequenceNumberCycles: %u\r\n",
3587 AS_OR(channel_string,
""),
3596 struct ast_json *json_rtcp_report_blocks;
3602 if (!json_rtcp_report_blocks) {
3607 struct ast_json *json_report_block;
3611 json_report_block =
ast_json_pack(
"{s: I, s: I, s: I, s: I, s: I, s: s, s: I}",
3619 if (!json_report_block
3632 json_rtcp_sender_info =
ast_json_pack(
"{s: s, s: s, s: I, s: I, s: I}",
3633 "ntp_timestamp_sec", sec,
3634 "ntp_timestamp_usec", usec,
3638 if (!json_rtcp_sender_info) {
3644 json_rtcp_report =
ast_json_pack(
"{s: I, s: I, s: i, s: o, s: o}",
3648 "sender_information", json_rtcp_sender_info ?:
ast_json_null(),
3649 "report_blocks", json_rtcp_report_blocks);
3650 if (!json_rtcp_report) {
3656 if (!json_channel) {
3664 "channel", json_channel,
3665 "rtcp_report", json_rtcp_report,
3666 "blob", payload->
blob);
3698 if (!message_type) {
3703 if (!payload || !report) {
3711 payload->blob = blob;
3715 payload->report = report;
3911 #ifdef USE_DEPRECATED_G726
4013 unsigned int ssrc = 0;
4026 const char *cname =
"";
4072#ifdef TEST_FRAMEWORK
4073size_t ast_rtp_instance_get_recv_buffer_max(
struct ast_rtp_instance *instance)
4076 struct ast_rtp_engine_test *
test = ast_rtp_instance_get_test(instance);
4084 res =
test->recv_buffer_max(instance);
4090size_t ast_rtp_instance_get_recv_buffer_count(
struct ast_rtp_instance *instance)
4093 struct ast_rtp_engine_test *
test = ast_rtp_instance_get_test(instance);
4101 res =
test->recv_buffer_count(instance);
4107size_t ast_rtp_instance_get_send_buffer_count(
struct ast_rtp_instance *instance)
4110 struct ast_rtp_engine_test *
test = ast_rtp_instance_get_test(instance);
4118 res =
test->send_buffer_count(instance);
4124void ast_rtp_instance_set_schedid(
struct ast_rtp_instance *instance,
int id)
4126 struct ast_rtp_engine_test *
test = ast_rtp_instance_get_test(instance);
4134 test->set_schedid(instance,
id);
4138void ast_rtp_instance_drop_packets(
struct ast_rtp_instance *instance,
int num)
4140 struct ast_rtp_engine_test *
test = ast_rtp_instance_get_test(instance);
4147 test->packets_to_drop = num;
4152 struct ast_rtp_engine_test *
test = ast_rtp_instance_get_test(instance);
4159 test->send_report = 1;
4164 struct ast_rtp_engine_test *
test = ast_rtp_instance_get_test(instance);
4171 return test->sdes_received;
4176 struct ast_rtp_engine_test *
test = ast_rtp_instance_get_test(instance);
4183 test->packets_to_drop = 0;
4184 test->send_report = 0;
4185 test->sdes_received = 0;