diff --git a/daemon/crypto.c b/daemon/crypto.c index d31d55d5a..be6632ab3 100644 --- a/daemon/crypto.c +++ b/daemon/crypto.c @@ -195,8 +195,8 @@ struct crypto_suite __crypto_suites[] = { .session_salt_len = 12, .srtp_lifetime = 1ULL << 48, .srtcp_lifetime = 1ULL << 31, - //.kernel_cipher = REC_AES_CM_128, - //.kernel_hmac = REH_HMAC_SHA1, + .kernel_cipher = REC_AEAD_AES_GCM_128, + .kernel_hmac = REH_NULL, .srtp_auth_tag = 0, .srtcp_auth_tag = 0, .srtp_auth_key_len = 0, @@ -205,10 +205,9 @@ struct crypto_suite __crypto_suites[] = { .decrypt_rtp = aes_gcm_decrypt_rtp, .encrypt_rtcp = aes_gcm_encrypt_rtcp, .decrypt_rtcp = aes_gcm_decrypt_rtcp, - //.hash_rtp = hmac_sha1_rtp, - //.hash_rtcp = hmac_sha1_rtcp, .session_key_init = aes_gcm_session_key_init, .session_key_cleanup = evp_session_key_cleanup, + .aead_evp = EVP_aes_128_gcm, }, { .name = "AEAD_AES_256_GCM", @@ -219,8 +218,8 @@ struct crypto_suite __crypto_suites[] = { .session_salt_len = 12, .srtp_lifetime = 1ULL << 48, .srtcp_lifetime = 1ULL << 31, - //.kernel_cipher = REC_AES_CM_256, - //.kernel_hmac = REH_HMAC_SHA1, + .kernel_cipher = REC_AEAD_AES_GCM_256, + .kernel_hmac = REH_NULL, .srtp_auth_tag = 0, .srtcp_auth_tag = 0, .srtp_auth_key_len = 0, @@ -229,10 +228,9 @@ struct crypto_suite __crypto_suites[] = { .decrypt_rtp = aes_gcm_decrypt_rtp, .encrypt_rtcp = aes_gcm_encrypt_rtcp, .decrypt_rtcp = aes_gcm_decrypt_rtcp, - //.hash_rtp = hmac_sha1_rtp, - //.hash_rtcp = hmac_sha1_rtcp, .session_key_init = aes_gcm_session_key_init, .session_key_cleanup = evp_session_key_cleanup, + .aead_evp = EVP_aes_256_gcm, }, { .name = "F8_128_HMAC_SHA1_80", @@ -466,23 +464,24 @@ int crypto_gen_session_key(struct crypto_context *c, str *out, unsigned char lab unsigned char x[14]; int i; + if (!out->len) + return 0; + ZERO(key_id); /* key_id[1..6] := r; or 1..4 for rtcp * key_derivation_rate == 0 --> r == 0 */ key_id[0] = label; + assert(sizeof(x) >= c->params.crypto_suite->master_salt_len); + memcpy(x, c->params.master_salt, c->params.crypto_suite->master_salt_len); // AEAD uses 12 bytes master salt; pad on the right to get 14 // Errata: https://www.rfc-editor.org/errata_search.php?rfc=7714 - if (c->params.crypto_suite->master_salt_len == 12) { - memcpy(x, c->params.master_salt, 12); + if (c->params.crypto_suite->master_salt_len == 12) x[12] = x[13] = '\x00'; - } else { - memcpy(x, c->params.master_salt, 14); - } for (i = 13 - index_len; i < 14; i++) x[i] = key_id[i - (13 - index_len)] ^ x[i]; - prf_n(out, c->params.master_key, c->params.crypto_suite->lib_cipher_ptr, x); + prf_n(out, c->params.master_key, c->params.crypto_suite->aes_evp, x); ilogs(srtp, LOG_DEBUG, "Generated session key: master key " "%02x%02x%02x%02x..., " @@ -563,18 +562,16 @@ static int aes_gcm_encrypt_rtp(struct crypto_context *c, struct rtp_header *r, s *(u_int32_t*)(iv+6) ^= htonl((idx & 0x00ffffffff0000ULL) >> 16); *(u_int16_t*)(iv+10) ^= htons(idx & 0x00ffffULL); - if (c->params.crypto_suite->session_key_len == 16) { - EVP_EncryptInit_ex(c->session_key_ctx[0], EVP_aes_128_gcm(), NULL, c->session_key, iv); - } else { - EVP_EncryptInit_ex(c->session_key_ctx[0], EVP_aes_256_gcm(), NULL, c->session_key, iv); - } + EVP_EncryptInit_ex(c->session_key_ctx[0], c->params.crypto_suite->aead_evp(), NULL, + (const unsigned char *) c->session_key, iv); // nominally 12 bytes of AAD EVP_EncryptUpdate(c->session_key_ctx[0], NULL, &len, (void *)r, s->s - (char *)r); - EVP_EncryptUpdate(c->session_key_ctx[0], s->s, &len, s->s, s->len); + EVP_EncryptUpdate(c->session_key_ctx[0], (unsigned char *) s->s, &len, + (const unsigned char *) s->s, s->len); ciphertext_len = len; - if (!EVP_EncryptFinal_ex(c->session_key_ctx[0], s->s+len, &len)) + if (!EVP_EncryptFinal_ex(c->session_key_ctx[0], (unsigned char *) s->s+len, &len)) return 1; ciphertext_len += len; // append the tag to the str buffer @@ -594,20 +591,18 @@ static int aes_gcm_decrypt_rtp(struct crypto_context *c, struct rtp_header *r, s *(u_int32_t*)(iv+6) ^= htonl((idx & 0x00ffffffff0000ULL) >> 16); *(u_int16_t*)(iv+10) ^= htons(idx & 0x00ffffULL); - if (c->params.crypto_suite->session_key_len == 16) { - EVP_DecryptInit_ex(c->session_key_ctx[0], EVP_aes_128_gcm(), NULL, c->session_key, iv); - } else { - EVP_DecryptInit_ex(c->session_key_ctx[0], EVP_aes_256_gcm(), NULL, c->session_key, iv); - } + EVP_DecryptInit_ex(c->session_key_ctx[0], c->params.crypto_suite->aead_evp(), NULL, + (const unsigned char *) c->session_key, iv); // nominally 12 bytes of AAD EVP_DecryptUpdate(c->session_key_ctx[0], NULL, &len, (void *)r, s->s - (char *)r); // decrypt partial buffer - the last 16 bytes are the tag - EVP_DecryptUpdate(c->session_key_ctx[0], s->s, &len, s->s, s->len-16); + EVP_DecryptUpdate(c->session_key_ctx[0], (unsigned char *) s->s, &len, + (const unsigned char *) s->s, s->len-16); plaintext_len = len; EVP_CIPHER_CTX_ctrl(c->session_key_ctx[0], EVP_CTRL_GCM_SET_TAG, 16, s->s + s->len-16); - if (!EVP_DecryptFinal_ex(c->session_key_ctx[0], s->s+len, &len)) + if (!EVP_DecryptFinal_ex(c->session_key_ctx[0], (unsigned char *) s->s+len, &len)) return 1; plaintext_len += len; s->len = plaintext_len; @@ -628,19 +623,17 @@ static int aes_gcm_encrypt_rtcp(struct crypto_context *c, struct rtcp_packet *r, *(u_int32_t*)(iv+8) ^= htonl(idx & 0x007fffffffULL); *(u_int32_t*)e_idx = htonl( (idx&0x007fffffffULL) | 0x80000000); - if (c->params.crypto_suite->session_key_len == 16) { - EVP_EncryptInit_ex(c->session_key_ctx[0], EVP_aes_128_gcm(), NULL, c->session_key, iv); - } else { - EVP_EncryptInit_ex(c->session_key_ctx[0], EVP_aes_256_gcm(), NULL, c->session_key, iv); - } + EVP_EncryptInit_ex(c->session_key_ctx[0], c->params.crypto_suite->aead_evp(), NULL, + (const unsigned char *) c->session_key, iv); // nominally 8 + 4 bytes of AAD EVP_EncryptUpdate(c->session_key_ctx[0], NULL, &len, (void *)r, s->s - (char *)r); EVP_EncryptUpdate(c->session_key_ctx[0], NULL, &len, (void *)e_idx, 4); - EVP_EncryptUpdate(c->session_key_ctx[0], s->s, &len, s->s, s->len); + EVP_EncryptUpdate(c->session_key_ctx[0], (unsigned char *) s->s, &len, + (const unsigned char *) s->s, s->len); ciphertext_len = len; - if (!EVP_EncryptFinal_ex(c->session_key_ctx[0], s->s+len, &len)) + if (!EVP_EncryptFinal_ex(c->session_key_ctx[0], (unsigned char *) s->s+len, &len)) return 1; ciphertext_len += len; // append the tag to the str buffer @@ -661,21 +654,19 @@ static int aes_gcm_decrypt_rtcp(struct crypto_context *c, struct rtcp_packet *r, *(u_int32_t*)(iv+8) ^= htonl(idx & 0x007fffffffULL); *(u_int32_t*)e_idx = htonl( (idx&0x007fffffffULL) | 0x80000000); - if (c->params.crypto_suite->session_key_len == 16) { - EVP_DecryptInit_ex(c->session_key_ctx[0], EVP_aes_128_gcm(), NULL, c->session_key, iv); - } else { - EVP_DecryptInit_ex(c->session_key_ctx[0], EVP_aes_256_gcm(), NULL, c->session_key, iv); - } + EVP_DecryptInit_ex(c->session_key_ctx[0], c->params.crypto_suite->aead_evp(), NULL, + (const unsigned char *) c->session_key, iv); // nominally 8 + 4 bytes of AAD EVP_DecryptUpdate(c->session_key_ctx[0], NULL, &len, (void *)r, s->s - (char *)r); EVP_DecryptUpdate(c->session_key_ctx[0], NULL, &len, (void *)e_idx, 4); // decrypt partial buffer - the last 16 bytes are the tag - EVP_DecryptUpdate(c->session_key_ctx[0], s->s, &len, s->s, s->len-16); + EVP_DecryptUpdate(c->session_key_ctx[0], (unsigned char *) s->s, &len, + (const unsigned char *) s->s, s->len-16); plaintext_len = len; EVP_CIPHER_CTX_ctrl(c->session_key_ctx[0], EVP_CTRL_GCM_SET_TAG, 16, s->s + s->len-16); - if (!EVP_DecryptFinal_ex(c->session_key_ctx[0], s->s+len, &len)) + if (!EVP_DecryptFinal_ex(c->session_key_ctx[0], (unsigned char *) s->s+len, &len)) return 1; plaintext_len += len; s->len = plaintext_len; @@ -826,7 +817,7 @@ static int aes_cm_session_key_init(struct crypto_context *c) { c->session_key_ctx[0] = g_slice_alloc(sizeof(EVP_CIPHER_CTX)); EVP_CIPHER_CTX_init(c->session_key_ctx[0]); #endif - EVP_EncryptInit_ex(c->session_key_ctx[0], c->params.crypto_suite->lib_cipher_ptr, NULL, + EVP_EncryptInit_ex(c->session_key_ctx[0], c->params.crypto_suite->aes_evp, NULL, (unsigned char *) c->session_key, NULL); return 0; } @@ -963,13 +954,13 @@ void crypto_init_main() { str_init(&cs->name_str, (char *) cs->name); switch(cs->master_key_len) { case 16: - cs->lib_cipher_ptr = EVP_aes_128_ecb(); + cs->aes_evp = EVP_aes_128_ecb(); break; case 24: - cs->lib_cipher_ptr = EVP_aes_192_ecb(); + cs->aes_evp = EVP_aes_192_ecb(); break; case 32: - cs->lib_cipher_ptr = EVP_aes_256_ecb(); + cs->aes_evp = EVP_aes_256_ecb(); break; } } diff --git a/daemon/dtls.c b/daemon/dtls.c index 7ffe8b8ca..685651d16 100644 --- a/daemon/dtls.c +++ b/daemon/dtls.c @@ -641,7 +641,7 @@ found: i += cs->master_salt_len; memcpy(server.master_salt, &keys[i], cs->master_salt_len); - ilogs(crypto, LOG_INFO, "DTLS-SRTP successfully negotiated"); + ilogs(crypto, LOG_INFO, "DTLS-SRTP successfully negotiated using %s", cs->name); if (d->active) { /* we're the client */ diff --git a/daemon/media_socket.c b/daemon/media_socket.c index c83f09947..d60300ffb 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -1033,6 +1033,8 @@ static int __k_srtp_crypt(struct rtpengine_srtp *s, struct crypto_context *c, st s->master_key_len = c->params.crypto_suite->master_key_len; s->session_key_len = c->params.crypto_suite->session_key_len; memcpy(s->master_salt, c->params.master_salt, c->params.crypto_suite->master_salt_len); + s->master_salt_len = c->params.crypto_suite->master_salt_len; + s->session_salt_len = c->params.crypto_suite->session_salt_len; if (c->params.session_params.unencrypted_srtp) s->cipher = REC_NULL; diff --git a/daemon/rtcp.c b/daemon/rtcp.c index 826e476b8..c8394b2fd 100644 --- a/daemon/rtcp.c +++ b/daemon/rtcp.c @@ -861,9 +861,11 @@ int rtcp_avp2savp(str *s, struct crypto_context *c, struct ssrc_ctx *ssrc_ctx) { rtcp->ssrc, ssrc_ctx->srtcp_index); crypto_debug_dump(&payload); + int prev_len = payload.len; if (!c->params.session_params.unencrypted_srtcp && crypto_encrypt_rtcp(c, rtcp, &payload, ssrc_ctx->srtcp_index)) return -1; + s->len += payload.len - prev_len; crypto_debug_printf(", enc pl: "); crypto_debug_dump(&payload); @@ -877,10 +879,12 @@ int rtcp_avp2savp(str *s, struct crypto_context *c, struct ssrc_ctx *ssrc_ctx) { rtp_append_mki(s, c); - c->params.crypto_suite->hash_rtcp(c, s->s + s->len, &to_auth); - crypto_debug_printf(", auth: "); - crypto_debug_dump_raw(s->s + s->len, c->params.crypto_suite->srtcp_auth_tag); - s->len += c->params.crypto_suite->srtcp_auth_tag; + if (c->params.crypto_suite->srtcp_auth_tag) { + c->params.crypto_suite->hash_rtcp(c, s->s + s->len, &to_auth); + crypto_debug_printf(", auth: "); + crypto_debug_dump_raw(s->s + s->len, c->params.crypto_suite->srtcp_auth_tag); + s->len += c->params.crypto_suite->srtcp_auth_tag; + } crypto_debug_finish(); @@ -923,6 +927,10 @@ int rtcp_savp2avp(str *s, struct crypto_context *c, struct ssrc_ctx *ssrc_ctx) { crypto_debug_printf(", idx %" PRIu32, idx); + if (!auth_tag.len) + goto decrypt; + + // authenticate assert(sizeof(hmac) >= auth_tag.len); c->params.crypto_suite->hash_rtcp(c, hmac, &to_auth); @@ -935,6 +943,8 @@ int rtcp_savp2avp(str *s, struct crypto_context *c, struct ssrc_ctx *ssrc_ctx) { if (str_memcmp(&auth_tag, hmac)) goto error; +decrypt:; + int prev_len = to_decrypt.len; if ((idx & 0x80000000ULL)) { if (crypto_decrypt_rtcp(c, rtcp, &to_decrypt, idx & 0x7fffffffULL)) return -1; @@ -945,6 +955,7 @@ int rtcp_savp2avp(str *s, struct crypto_context *c, struct ssrc_ctx *ssrc_ctx) { *s = to_auth; s->len -= sizeof(idx); + s->len -= prev_len - to_decrypt.len; crypto_debug_finish(); diff --git a/daemon/rtp.c b/daemon/rtp.c index db874a293..85e48f6eb 100644 --- a/daemon/rtp.c +++ b/daemon/rtp.c @@ -118,8 +118,10 @@ int rtp_avp2savp(str *s, struct crypto_context *c, struct ssrc_ctx *ssrc_ctx) { crypto_debug_dump(&payload); /* rfc 3711 section 3.1 */ + int prev_len = payload.len; if (!c->params.session_params.unencrypted_srtp && crypto_encrypt_rtp(c, rtp, &payload, index)) return -1; + s->len += payload.len - prev_len; crypto_debug_printf(", enc pl: "); crypto_debug_dump(&payload); @@ -212,7 +214,8 @@ int rtp_savp2avp(str *s, struct crypto_context *c, struct ssrc_ctx *ssrc_ctx) { decrypt_idx: ssrc_ctx->srtp_index = index; -decrypt: +decrypt:; + int prev_len = to_decrypt.len; if (!c->params.session_params.unencrypted_srtp && crypto_decrypt_rtp(c, rtp, &to_decrypt, index)) return -1; @@ -220,6 +223,7 @@ decrypt: crypto_debug_dump(&to_decrypt); *s = to_auth; + s->len -= prev_len - to_decrypt.len; crypto_debug_finish(); diff --git a/include/crypto.h b/include/crypto.h index 0c50725e8..5af7d687e 100644 --- a/include/crypto.h +++ b/include/crypto.h @@ -56,9 +56,10 @@ struct crypto_suite { session_key_init_func session_key_init; session_key_cleanup_func session_key_cleanup; //const char *dtls_profile_code; // unused - const void *lib_cipher_ptr; + const EVP_CIPHER *aes_evp; unsigned int idx; // filled in during crypto_init_main() str name_str; // same as `name` + const EVP_CIPHER *(*aead_evp)(void); }; struct crypto_session_params { diff --git a/kernel-module/.gitignore b/kernel-module/.gitignore index fe90a98c8..fc5e8de35 100644 --- a/kernel-module/.gitignore +++ b/kernel-module/.gitignore @@ -5,3 +5,4 @@ modules.order Module.symvers .*.cmd +xt_RTPENGINE.mod diff --git a/kernel-module/xt_RTPENGINE.c b/kernel-module/xt_RTPENGINE.c index 169c89a98..75d26b46e 100644 --- a/kernel-module/xt_RTPENGINE.c +++ b/kernel-module/xt_RTPENGINE.c @@ -10,6 +10,9 @@ #include #include #include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) +#include +#endif #include #include #include @@ -41,7 +44,7 @@ MODULE_LICENSE("GPL"); #define MAX_ID 64 /* - 1 */ -#define MAX_SKB_TAIL_ROOM (sizeof(((struct rtpengine_srtp *) 0)->mki) + 20) +#define MAX_SKB_TAIL_ROOM (sizeof(((struct rtpengine_srtp *) 0)->mki) + 20 + 16) #define MIPF "%i:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x:%u" #define MIPP(x) (x).family, \ @@ -155,6 +158,7 @@ struct re_auto_array; struct re_call; struct re_stream; struct rtpengine_table; +struct crypto_aead; @@ -232,6 +236,10 @@ static int srtp_encrypt_aes_cm(struct re_crypto_context *, struct rtpengine_srtp struct rtp_parsed *, u_int64_t); static int srtp_encrypt_aes_f8(struct re_crypto_context *, struct rtpengine_srtp *, struct rtp_parsed *, u_int64_t); +static int srtp_encrypt_aes_gcm(struct re_crypto_context *, struct rtpengine_srtp *, + struct rtp_parsed *, u_int64_t); +static int srtp_decrypt_aes_gcm(struct re_crypto_context *, struct rtpengine_srtp *, + struct rtp_parsed *, u_int64_t); static void call_put(struct re_call *call); static void del_stream(struct re_stream *stream, struct rtpengine_table *); @@ -253,6 +261,7 @@ struct re_crypto_context { u_int32_t roc; struct crypto_cipher *tfm[2]; struct crypto_shash *shash; + struct crypto_aead *aead; const struct re_cipher *cipher; const struct re_hmac *hmac; }; @@ -389,6 +398,7 @@ struct re_cipher { enum rtpengine_cipher id; const char *name; const char *tfm_name; + const char *aead_name; int (*decrypt)(struct re_crypto_context *, struct rtpengine_srtp *, struct rtp_parsed *, u_int64_t); int (*encrypt)(struct re_crypto_context *, struct rtpengine_srtp *, @@ -572,6 +582,20 @@ static const struct re_cipher re_ciphers[] = { .decrypt = srtp_encrypt_aes_cm, .encrypt = srtp_encrypt_aes_cm, }, + [REC_AEAD_AES_GCM_128] = { + .id = REC_AEAD_AES_GCM_128, + .name = "AEAD-AES-GCM-128", + .aead_name = "gcm(aes)", + .decrypt = srtp_decrypt_aes_gcm, + .encrypt = srtp_encrypt_aes_gcm, + }, + [REC_AEAD_AES_GCM_256] = { + .id = REC_AEAD_AES_GCM_256, + .name = "AEAD-AES-GCM-256", + .aead_name = "gcm(aes)", + .decrypt = srtp_decrypt_aes_gcm, + .encrypt = srtp_encrypt_aes_gcm, + }, }; static const struct re_hmac re_hmacs[] = { @@ -816,6 +840,10 @@ static void free_crypto_context(struct re_crypto_context *c) { } if (c->shash) crypto_free_shash(c->shash); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) + if (c->aead) + crypto_free_aead(c->aead); +#endif } static void target_put(struct rtpengine_target *t) { @@ -1939,7 +1967,11 @@ static int gen_session_key(unsigned char *out, int len, struct rtpengine_srtp *s key_id[0] = label; - memcpy(x, s->master_salt, 14); + memcpy(x, s->master_salt, s->master_salt_len); + // AEAD uses 12 bytes master salt; pad on the right to get 14 + // Errata: https://www.rfc-editor.org/errata_search.php?rfc=7714 + if (s->master_salt_len == 12) + x[12] = x[13] = '\x00'; for (i = 13 - 6; i < 14; i++) x[i] = key_id[i - (13 - 6)] ^ x[i]; @@ -1987,10 +2019,10 @@ static int gen_session_keys(struct re_crypto_context *c, struct rtpengine_srtp * ret = gen_session_key(c->session_key, s->session_key_len, s, 0x00); if (ret) goto error; - ret = gen_session_key(c->session_auth_key, 20, s, 0x01); + ret = gen_session_key(c->session_auth_key, 20, s, 0x01); // XXX fixed length auth key if (ret) goto error; - ret = gen_session_key(c->session_salt, 14, s, 0x02); + ret = gen_session_key(c->session_salt, s->session_salt_len, s, 0x02); if (ret) goto error; @@ -2002,9 +2034,36 @@ static int gen_session_keys(struct re_crypto_context *c, struct rtpengine_srtp * c->tfm[0] = NULL; goto error; } - crypto_cipher_setkey(c->tfm[0], c->session_key, s->session_key_len); + ret = crypto_cipher_setkey(c->tfm[0], c->session_key, s->session_key_len); + if (ret) + goto error; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) + if (c->cipher->aead_name) { + err = "failed to load AEAD"; + c->aead = crypto_alloc_aead(c->cipher->aead_name, 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(c->aead)) { + ret = PTR_ERR(c->aead); + c->aead = NULL; + goto error; + } + ret = -EINVAL; + if (crypto_aead_ivsize(c->aead) != 12) + goto error; + ret = crypto_aead_setkey(c->aead, c->session_key, s->session_key_len); + if (ret) + goto error; + ret = crypto_aead_setauthsize(c->aead, 16); + if (ret) + goto error; + } +#else + err = "No support for AEAD in this kernel"; + if (c->cipher->aead_name) + goto error; +#endif + if (c->cipher->session_key_init) { ret = c->cipher->session_key_init(c, s); if (ret) @@ -2019,7 +2078,9 @@ static int gen_session_keys(struct re_crypto_context *c, struct rtpengine_srtp * c->shash = NULL; goto error; } - crypto_shash_setkey(c->shash, c->session_auth_key, 20); + ret = crypto_shash_setkey(c->shash, c->session_auth_key, 20); + if (ret) + goto error; } switch(s->master_key_len) { @@ -3857,6 +3918,98 @@ static int srtp_encrypt_aes_f8(struct re_crypto_context *c, return 0; } +static int srtp_encrypt_aes_gcm(struct re_crypto_context *c, + struct rtpengine_srtp *s, struct rtp_parsed *r, + u_int64_t pkt_idx) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) + unsigned char iv[12]; + struct aead_request *req; + struct scatterlist sg[2]; + int ret; + + if (s->session_salt_len != 12) + return -EINVAL; + if (r->payload_len < 16) + return -EINVAL; + + memcpy(iv, c->session_salt, 12); + + *(u_int32_t*)(iv+2) ^= r->header->ssrc; + *(u_int32_t*)(iv+6) ^= htonl((pkt_idx & 0x00ffffffff0000ULL) >> 16); + *(u_int16_t*)(iv+10) ^= htons(pkt_idx & 0x00ffffULL); + + req = aead_request_alloc(c->aead, GFP_ATOMIC); + if (!req) + return -ENOMEM; + if (IS_ERR(req)) + return PTR_ERR(req); + + sg_init_table(sg, ARRAY_SIZE(sg)); + sg_set_buf(&sg[0], r->header, r->header_len); + sg_set_buf(&sg[1], r->payload, r->payload_len + 16); // guaranteed to have space after skb_copy_expand + + aead_request_set_callback(req, 0, NULL, NULL); + aead_request_set_ad(req, r->header_len); + aead_request_set_crypt(req, sg, sg, r->payload_len, iv); + + ret = crypto_aead_encrypt(req); + aead_request_free(req); + + if (ret == 0) + r->payload_len += 16; + + return ret; +#else + return -EOPNOTSUPP; +#endif +} +static int srtp_decrypt_aes_gcm(struct re_crypto_context *c, + struct rtpengine_srtp *s, struct rtp_parsed *r, + u_int64_t pkt_idx) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) + unsigned char iv[12]; + struct aead_request *req; + struct scatterlist sg[2]; + int ret; + + if (s->session_salt_len != 12) + return -EINVAL; + if (r->payload_len < 16) + return -EINVAL; + + memcpy(iv, c->session_salt, 12); + + *(u_int32_t*)(iv+2) ^= r->header->ssrc; + *(u_int32_t*)(iv+6) ^= htonl((pkt_idx & 0x00ffffffff0000ULL) >> 16); + *(u_int16_t*)(iv+10) ^= htons(pkt_idx & 0x00ffffULL); + + req = aead_request_alloc(c->aead, GFP_ATOMIC); + if (!req) + return -ENOMEM; + if (IS_ERR(req)) + return PTR_ERR(req); + + sg_init_table(sg, ARRAY_SIZE(sg)); + sg_set_buf(&sg[0], r->header, r->header_len); + sg_set_buf(&sg[1], r->payload, r->payload_len); + + aead_request_set_callback(req, 0, NULL, NULL); + aead_request_set_ad(req, r->header_len); + aead_request_set_crypt(req, sg, sg, r->payload_len, iv); + + ret = crypto_aead_decrypt(req); + aead_request_free(req); + + if (ret == 0) + r->payload_len -= 16; + + return ret; +#else + return -EOPNOTSUPP; +#endif +} static inline int srtp_encrypt(struct re_crypto_context *c, struct rtpengine_srtp *s, struct rtp_parsed *r, diff --git a/kernel-module/xt_RTPENGINE.h b/kernel-module/xt_RTPENGINE.h index 217903e8a..6ce65f913 100644 --- a/kernel-module/xt_RTPENGINE.h +++ b/kernel-module/xt_RTPENGINE.h @@ -54,6 +54,8 @@ enum rtpengine_cipher { REC_AES_F8, REC_AES_CM_192, REC_AES_CM_256, + REC_AEAD_AES_GCM_128, + REC_AEAD_AES_GCM_256, __REC_LAST }; @@ -73,7 +75,9 @@ struct rtpengine_srtp { unsigned char master_key[32]; unsigned int master_key_len; unsigned char master_salt[14]; + unsigned int master_salt_len; unsigned int session_key_len; + unsigned int session_salt_len; unsigned char mki[256]; /* XXX uses too much memory? */ u_int64_t last_index; unsigned int auth_tag_len; /* in bytes */ diff --git a/perl/NGCP/Rtpengine/AutoTest.pm b/perl/NGCP/Rtpengine/AutoTest.pm index 770ad42ba..d91fe2cfc 100644 --- a/perl/NGCP/Rtpengine/AutoTest.pm +++ b/perl/NGCP/Rtpengine/AutoTest.pm @@ -122,8 +122,10 @@ sub offer_answer { $regexp =~ s/ICEBASE/([0-9a-zA-Z]{16})/gs; $regexp =~ s/ICEUFRAG/([0-9a-zA-Z]{8})/gs; $regexp =~ s/ICEPWD/([0-9a-zA-Z]{26})/gs; + $regexp =~ s/CRYPTO128S/([0-9a-zA-Z\/+]{38})/gs; $regexp =~ s/CRYPTO128/([0-9a-zA-Z\/+]{40})/gs; $regexp =~ s/CRYPTO192/([0-9a-zA-Z\/+]{51})/gs; + $regexp =~ s/CRYPTO256S/([0-9a-zA-Z\/+]{59})/gs; $regexp =~ s/CRYPTO256/([0-9a-zA-Z\/+]{62})/gs; $regexp =~ s/LOOPER/([0-9a-f]{12})/gs; $regexp =~ s/FINGERPRINT256/([0-9a-fA-F:]{95})/gs; diff --git a/t/.gitignore b/t/.gitignore index 453cf88cc..3429703e3 100644 --- a/t/.gitignore +++ b/t/.gitignore @@ -60,3 +60,4 @@ spandsp_recv_fax_t38 spandsp_send_fax_pcm spandsp_send_fax_t38 spandsp_logging.h +aead-aes-crypt diff --git a/t/aead-aes-crypt.c b/t/aead-aes-crypt.c index 8b095f521..814b7a482 100644 --- a/t/aead-aes-crypt.c +++ b/t/aead-aes-crypt.c @@ -97,7 +97,7 @@ uint8_t answer256_srtcp[72] = { struct rtpengine_config rtpe_config = { }; -int main(int argc, char *argv) +int main(void) { str suite, payload; @@ -122,7 +122,7 @@ int main(int argc, char *argv) memcpy(working, srtp_pt, 50); payload.len = 38; - payload.s = working + 12; + payload.s = (char *) working + 12; rc = crypto_encrypt_rtp(&ctx, (struct rtp_header *)working, &payload, @@ -132,7 +132,7 @@ int main(int argc, char *argv) printf("RTP/AEAD-AES-128-GCM Encrypt - PASS\n"); payload.len = 54; - payload.s = working + 12; + payload.s = (char *) working + 12; rc = crypto_decrypt_rtp(&ctx, (struct rtp_header *)working, &payload, @@ -145,7 +145,7 @@ int main(int argc, char *argv) // RTCP memcpy(working, srtcp_pt, 52); payload.len = 44; - payload.s = working + 8; + payload.s = (char *) working + 8; rc = crypto_encrypt_rtcp(&ctx, (struct rtcp_packet *)working, &payload, @@ -155,7 +155,7 @@ int main(int argc, char *argv) printf("RTCP/AEAD-AES-128-GCM Encrypt - PASS\n"); payload.len = 60; - payload.s = working + 8; + payload.s = (char *) working + 8; rc = crypto_decrypt_rtcp(&ctx, (struct rtcp_packet *)working, &payload, @@ -179,7 +179,7 @@ int main(int argc, char *argv) memcpy(working, srtp_pt, 50); payload.len = 38; - payload.s = working + 12; + payload.s = (char *) working + 12; rc = crypto_encrypt_rtp(&ctx, (struct rtp_header *)working, &payload, @@ -189,7 +189,7 @@ int main(int argc, char *argv) printf("RTP/AEAD-AES-256-GCM Encrypt - PASS\n"); payload.len = 54; - payload.s = working + 12; + payload.s = (char *) working + 12; rc = crypto_decrypt_rtp(&ctx, (struct rtp_header *)working, &payload, @@ -201,7 +201,7 @@ int main(int argc, char *argv) // RTCP memcpy(working, srtcp_pt, 52); payload.len = 44; - payload.s = working + 8; + payload.s = (char *) working + 8; rc = crypto_encrypt_rtcp(&ctx, (struct rtcp_packet *)working, &payload, @@ -211,7 +211,7 @@ int main(int argc, char *argv) printf("RTCP/AEAD-AES-256-GCM Encrypt - PASS\n"); payload.len = 60; - payload.s = working + 8; + payload.s = (char *) working + 8; rc = crypto_decrypt_rtcp(&ctx, (struct rtcp_packet *)working, &payload, diff --git a/t/auto-daemon-tests-reorder.pl b/t/auto-daemon-tests-reorder.pl index 933f7187f..f2fc18d0a 100755 --- a/t/auto-daemon-tests-reorder.pl +++ b/t/auto-daemon-tests-reorder.pl @@ -3933,329 +3933,6 @@ SDP -# GH 1086 - -new_call; - -offer('GH 1086', { - ICE => 'remove', - flags => [], - 'transport-protocol' => 'RTP/SAVP', - }, < ft() }); - -offer('GH 1086', { - ICE => 'remove', - flags => [], - 'transport-protocol' => 'RTP/SAVP', - }, < 'remove', - flags => [], - 'transport-protocol' => 'RTP/SAVP', - DTLS => 'off', - }, < 'remove', - flags => [], - DTLS => 'off', - }, < 'remove', - flags => [], - 'transport-protocol' => 'RTP/SAVP', - DTLS => 'off', - }, < 'remove', - flags => [], - DTLS => 'off', - 'transport-protocol' => 'accept', - }, < 'remove', - flags => [], - 'transport-protocol' => 'RTP/SAVP', - DTLS => 'off', - }, < 'remove', - flags => [], - DTLS => 'off', - 'transport-protocol' => 'RTP/AVPF', - }, < 'remove', - SDES => 'off', - 'via-branch' => 'foo.0', - 'transport-protocol' => 'RTP/SAVPF', - 'rtcp-mux' => ['offer'], - }, < 'remove', }, < 'remove', - SDES => 'off', - 'via-branch' => 'foo.1', - 'transport-protocol' => 'RTP/AVP', - 'rtcp-mux' => ['demux'], - }, < 'remove', }, < ft(), 'via-branch' => 'foo.1' }); +snd($sock_a, $port_b, rtp(8, 1000, 3000, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1000, 3000, 0x1234, "\x00" x 160)); +snd($sock_b, $port_a, rtp(8, 2000, 4000, 0x3210, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(8, 2000, 4000, 0x3210, "\x00" x 160)); -answer('rtcp-mux branched w delete-delay', { - ICE => 'remove', - SDES => 'off', - 'via-branch' => 'foo.0', - 'transport-protocol' => 'RTP/AVPF', - 'rtcp-mux' => ['demux'], - }, < ft(), blob => $wav_file }); +is $resp->{duration}, 100, 'media duration'; + +($seq, $ts, $ssrc) = rcv($sock_a, $port_b, rtpm(8 | 0x80, -1, -1, -1, $pcma_1)); +# SR LEN SSRC NTP1 NTP2 RTP PACKETS OCTETS SSRC LOST SEQ JITTER LAST SR DLSR CNAME +@ret1 = rcv($sock_ax, $port_bx, qr/^\x81\xc8\x00\x0c(.{4})(.{4})(.{4})(.{4})\x00\x00\x00\x01\x00\x00\x00\xac\x00\x00\x12\x34\x00\x00\x00\x00\x00\x00\x03\xe8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\xca\x00\x05(.{4})\x01\x0c([0-9a-f]{12})\x00\x00$/s); +is $ret1[0], $ssrc, 'SSRC matches'; +is $ret1[3], $ts, 'TS matches'; +is $ret1[4], $ssrc, 'SSRC matches'; +rtpe_req('delete', "delete", { 'from-tag' => ft() }); -new_call; -offer('rtcp-mux branched delete-delay=0', { - ICE => 'remove', - SDES => 'off', - 'via-branch' => 'foo.0', - 'transport-protocol' => 'RTP/SAVPF', - 'rtcp-mux' => ['offer'], - }, < 'remove', }, < 'remove', - SDES => 'off', - 'via-branch' => 'foo.1', - 'transport-protocol' => 'RTP/AVP', - 'rtcp-mux' => ['demux'], - }, < 'remove', }, < ft(), 'via-branch' => 'foo.1', - 'delete-delay' => 0, - }); +snd($sock_a, $port_b, rtp(8, 1000, 3000, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1000, 3000, 0x1234, "\x00" x 160)); +snd($sock_b, $port_a, rtp(8, 2000, 4000, 0x3210, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(8, 2000, 4000, 0x3210, "\x00" x 160)); -answer('rtcp-mux branched delete-delay=0', { - ICE => 'remove', - SDES => 'off', - 'via-branch' => 'foo.0', - 'transport-protocol' => 'RTP/AVPF', - 'rtcp-mux' => ['demux'], - }, < ft(), blob => $wav_file }); +is $resp->{duration}, 100, 'media duration'; +($seq, $ts, $ssrc) = rcv($sock_a, $port_b, rtpm(8 | 0x80, -1, -1, -1, $pcma_1)); +# SR LEN SSRC NTP1 NTP2 RTP PACKETS OCTETS SSRC LOST SEQ JITTER LAST SR DLSR CNAME +@ret1 = rcv($sock_ax, $port_bx, qr/^\x81\xc8\x00\x0c(.{4})(.{4})(.{4})(.{4})\x00\x00\x00\x01\x00\x00\x00\xac\x00\x00\x12\x34\x00\x00\x00\x00\x00\x00\x03\xe8\x00\x00\x00\x00\x56\x78\x9a\xbc(.{4})\x81\xca\x00\x05(.{4})\x01\x0c([0-9a-f]{12})\x00\x00$/s); +is $ret1[0], $ssrc, 'SSRC matches'; +is $ret1[3], $ts, 'TS matches'; +cmp_ok $ret1[4], '<', 1000, 'DSLR ok'; +is $ret1[5], $ssrc, 'SSRC matches'; +rtpe_req('delete', "delete", { 'from-tag' => ft() }); -# RTP to SRTP switch (and SRTP re-invite) TT#81850 +# MSRP (GH 959) -new_call; +new_call(); -(undef, undef, $srtp_key_a) = offer('RTP to SRTP switch (and SRTP re-invite)', - { "transport-protocol" => "RTP/SAVP", "ICE" => "remove", "rtcp-mux" => [ "demux" ], - DTLS => 'off', - "replace" => [ "origin", "session-connection" ], - "via-branch" => "z9hG4bK0ae8.cc3c994fa8d0c0f1f2536bba541306fb.0", - }, < "remove", "rtcp-mux" => [ "demux" ], - DTLS => 'off', - "replace" => [ "origin", "session-connection" ], - "via-branch" => "z9hG4bK0ae8.cc3c994fa8d0c0f1f2536bba541306fb.0", - }, < "RTP/SAVP", "ICE" => "remove", "rtcp-mux" => [ "demux" ], - DTLS => 'off', - "replace" => [ "origin", "session-connection" ], - "via-branch" => "z9hG4bK0ae8.cc3c994fa8d0c0f1f2536bba541306fb.0", - 'to-tag' => tt(), - }, < "remove", "rtcp-mux" => [ "demux" ], - DTLS => 'off', - "replace" => [ "origin", "session-connection" ], - "via-branch" => "z9hG4bK0ae8.cc3c994fa8d0c0f1f2536bba541306fb.0", - }, < 'remove', }, < "RTP/SAVP", "ICE" => "remove", "rtcp-mux" => [ "demux" ], - DTLS => 'off', - "replace" => [ "origin", "session-connection" ], - "via-branch" => "z9hG4bK0ae8.cc3c994fa8d0c0f1f2536bba541306fb.0", - 'to-tag' => tt(), - }, < 'remove', replace => ['origin'], DTLS => 'off', - 'transport-protocol' => 'RTP/SAVP', flags => ['inject-DTMF'], - 'rtcp-mux' => ['demux'] }, < 'remove', codec => { mask => ['full'], transcode => ['PCMA','telephone-event'] } }, < 'remove', replace => ['origin'], DTLS => 'off', ICE => 'remove', - flags => ['inject-DTMF'], 'rtcp-mux' => ['demux'] }, < 'remove', }, < $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_80}, - key => 'QjnnaukLn7iwASAs0YLzPUplJkjOhTZK2dvOwo6c', -}; -$srtp_ctx_b = { - cs => $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_80}, - key => 'cdDuBSOp/rX/7ikmU1Tnuu337gXUUMFAhkARhB/j', -}; - - -srtp_snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 160), $srtp_ctx_a); -srtp_rcv($sock_b, $port_a, rtpm(0, 1000, 3000, -1, "\x00" x 160), $srtp_ctx_a); -srtp_snd($sock_b, $port_a, rtp(0, 2000, 4000, 0x6543, "\x00" x 160), $srtp_ctx_b); -srtp_rcv($sock_a, $port_b, rtpm(0, 2000, 4000, -1, "\x00" x 160), $srtp_ctx_b); - - -# RTCP -($sock_a, $sock_ax, $sock_b, $sock_bx) = new_call( - [qw(198.51.100.1 7400)], - [qw(198.51.100.1 7401)], - [qw(198.51.100.3 7402)], - [qw(198.51.100.3 7403)], -); +new_call(); -($port_a, $port_ax) = offer('RTCP player', { ICE => 'remove', }, < 'remove', codec => { mask => ['all'], transcode => ['PCMA','telephone-event'] } }, < 'remove', }, < 'remove', }, < ft(), blob => $wav_file }); -is $resp->{duration}, 100, 'media duration'; - -($seq, $ts, $ssrc) = rcv($sock_a, $port_b, rtpm(8 | 0x80, -1, -1, -1, $pcma_1)); -# SR LEN SSRC NTP1 NTP2 RTP PACKETS OCTETS SSRC LOST SEQ JITTER LAST SR DLSR CNAME -@ret1 = rcv($sock_ax, $port_bx, qr/^\x81\xc8\x00\x0c(.{4})(.{4})(.{4})(.{4})\x00\x00\x00\x01\x00\x00\x00\xac\x00\x00\x12\x34\x00\x00\x00\x00\x00\x00\x03\xe8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\xca\x00\x05(.{4})\x01\x0c([0-9a-f]{12})\x00\x00$/s); -is $ret1[0], $ssrc, 'SSRC matches'; -is $ret1[3], $ts, 'TS matches'; -is $ret1[4], $ssrc, 'SSRC matches'; -rtpe_req('delete', "delete", { 'from-tag' => ft() }); +# symmetric-codec flag (GH 953) -($sock_a, $sock_ax, $sock_b, $sock_bx) = new_call( - [qw(198.51.100.1 7400)], - [qw(198.51.100.1 7401)], - [qw(198.51.100.3 7402)], - [qw(198.51.100.3 7403)], -); +new_call(); -($port_a, $port_ax) = offer('RTCP player w/ previous SR', { ICE => 'remove', }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', }, < 'remove', }, < 'remove', codec => { transcode => ['G722'] } }, < ft(), blob => $wav_file }); -is $resp->{duration}, 100, 'media duration'; - -($seq, $ts, $ssrc) = rcv($sock_a, $port_b, rtpm(8 | 0x80, -1, -1, -1, $pcma_1)); -# SR LEN SSRC NTP1 NTP2 RTP PACKETS OCTETS SSRC LOST SEQ JITTER LAST SR DLSR CNAME -@ret1 = rcv($sock_ax, $port_bx, qr/^\x81\xc8\x00\x0c(.{4})(.{4})(.{4})(.{4})\x00\x00\x00\x01\x00\x00\x00\xac\x00\x00\x12\x34\x00\x00\x00\x00\x00\x00\x03\xe8\x00\x00\x00\x00\x56\x78\x9a\xbc(.{4})\x81\xca\x00\x05(.{4})\x01\x0c([0-9a-f]{12})\x00\x00$/s); -is $ret1[0], $ssrc, 'SSRC matches'; -is $ret1[3], $ts, 'TS matches'; -cmp_ok $ret1[4], '<', 1000, 'DSLR ok'; -is $ret1[5], $ssrc, 'SSRC matches'; - -rtpe_req('delete', "delete", { 'from-tag' => ft() }); - +answer('gh 953 w/ flag', { ICE => 'remove', flags => ['symmetric codecs'] }, < 'remove', replace => ['origin'], DTLS => 'off' }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', replace => ['origin'], DTLS => 'off' }, < 'remove', }, < $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_32}, - key => 'Kl3GFJ5Gqz5x07xYkoyHODkVkSpiplZnXsQIw+Q7', -}; -$srtp_ctx_a_rev = { - cs => $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_32}, - key => $srtp_key_a, -}; -$srtp_ctx_b = { - cs => $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_80}, - key => 'Qk0TvVeyfqfjFd/YebnyyklqSEhJntpVKV1KAhHa', -}; -$srtp_ctx_b_rev = { - cs => $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_80}, - key => $srtp_key_b, -}; - -srtp_snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 160), $srtp_ctx_b); -srtp_rcv($sock_b, $port_a, rtpm(0, 1000, 3000, 0x1234, "\x00" x 160), $srtp_ctx_a_rev); -srtp_snd($sock_b, $port_a, rtp(0, 2000, 4000, 0x3456, "\x00" x 160), $srtp_ctx_a); -srtp_rcv($sock_a, $port_b, rtpm(0, 2000, 4000, 0x3456, "\x00" x 160), $srtp_ctx_b_rev); - +# XXX ^ problem here? combine with single-codec? -# OSRTP -($sock_a, $sock_b) = new_call([qw(198.51.100.1 3316)], [qw(198.51.100.3 3318)]); +new_call(); -($port_a) = offer('OSRTP offer, accept, same suite', - { ICE => 'remove', replace => ['origin'], DTLS => 'off' }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', replace => ['origin'], DTLS => 'off' }, < 'remove', flags => ['symmetric codecs'] }, < $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_80}, - key => 'Kl3GFJ5Gqz5x07xYkoyHODkVkSpiplZnXsQIw+Q7', -}; -$srtp_ctx_b = { - cs => $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_80}, - key => 'Qk0TvVeyfqfjFd/YebnyyklqSEhJntpVKV1KAhHa', -}; -srtp_snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 160), $srtp_ctx_a); -srtp_rcv($sock_b, $port_a, rtpm(0, 1000, 3000, 0x1234, "\x00" x 160), $srtp_ctx_a); -srtp_snd($sock_b, $port_a, rtp(0, 2000, 4000, 0x3456, "\x00" x 160), $srtp_ctx_b); -srtp_rcv($sock_a, $port_b, rtpm(0, 2000, 4000, 0x3456, "\x00" x 160), $srtp_ctx_b); -($sock_a, $sock_b) = new_call([qw(198.51.100.1 3320)], [qw(198.51.100.3 3322)]); +new_call(); -($port_a, undef, $srtp_key_a) = offer('OSRTP offer, accept, diff suite', - { ICE => 'remove', replace => ['origin'], DTLS => 'off' }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', replace => ['origin'], DTLS => 'off' }, < 'remove', }, < $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_32}, - key => 'Kl3GFJ5Gqz5x07xYkoyHODkVkSpiplZnXsQIw+Q7', -}; -$srtp_ctx_a_rev = { - cs => $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_32}, - key => $srtp_key_a, -}; -$srtp_ctx_b = { - cs => $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_80}, - key => 'Qk0TvVeyfqfjFd/YebnyyklqSEhJntpVKV1KAhHa', -}; -$srtp_ctx_b_rev = { - cs => $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_80}, - key => $srtp_key_b, -}; - -srtp_snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 160), $srtp_ctx_b); -srtp_rcv($sock_b, $port_a, rtpm(0, 1000, 3000, 0x1234, "\x00" x 160), $srtp_ctx_a_rev); -srtp_snd($sock_b, $port_a, rtp(0, 2000, 4000, 0x3456, "\x00" x 160), $srtp_ctx_a); -srtp_rcv($sock_a, $port_b, rtpm(0, 2000, 4000, 0x3456, "\x00" x 160), $srtp_ctx_b_rev); - -($sock_a, $sock_b) = new_call([qw(198.51.100.1 3324)], [qw(198.51.100.3 3326)]); +new_call(); -($port_a) = offer('OSRTP offer, reject', - { ICE => 'remove', replace => ['origin'], DTLS => 'off' }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', flags => ['symmetric codecs'] }, < 'remove', replace => ['origin'], DTLS => 'off' }, < [ 'decode' ], ICE => 'remove', + }, < ft() }); -($sock_a, $sock_b) = new_call([qw(198.51.100.1 3324)], [qw(198.51.100.3 3326)]); -($port_a) = offer('OSRTP offer, reject w/ accept flag', - { ICE => 'remove', replace => ['origin'], DTLS => 'off' }, < 'remove', + }, < 'remove', replace => ['origin'], DTLS => 'off', OSRTP => ['accept'] }, < 'remove', + }, < $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_80}, - key => $srtp_key_a, -}; -$srtp_ctx_b = { - cs => $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_80}, - key => 'Qk0TvVeyfqfjFd/YebnyyklqSEhJntpVKV1KAhHa', -}; - -srtp_snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 160), $srtp_ctx_b); -rcv($sock_b, $port_a, rtpm(0, 1000, 3000, 0x1234, "\x00" x 160)); -snd($sock_b, $port_a, rtp(0, 2000, 4000, 0x3456, "\x00" x 160)); -srtp_rcv($sock_a, $port_b, rtpm(0, 2000, 4000, 0x3456, "\x00" x 160), $srtp_ctx_a); - - - - - -($sock_a, $sock_b) = new_call([qw(198.51.100.1 3336)], [qw(198.51.100.3 3338)]); - -($port_a, undef, $srtp_key_a) = offer('non-OSRTP offer with offer flag, accept', - { ICE => 'remove', replace => ['origin'], DTLS => 'off', OSRTP => ['offer'] }, < 'remove', 'T.38' => [ 'force' ], + }, < 'remove', replace => ['origin'], DTLS => 'off', }, < 'remove', + }, < $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_80}, - key => 'Kl3GFJ5Gqz5x07xYkoyHODkVkSpiplZnXsQIw+Q7', -}; -$srtp_ctx_b = { - cs => $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_80}, - key => $srtp_key_a, -}; - -snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 160)); -srtp_rcv($sock_b, $port_a, rtpm(0, 1000, 3000, 0x1234, "\x00" x 160), $srtp_ctx_b); -srtp_snd($sock_b, $port_a, rtp(0, 2000, 4000, 0x3456, "\x00" x 160), $srtp_ctx_a); -rcv($sock_a, $port_b, rtpm(0, 2000, 4000, 0x3456, "\x00" x 160)); +rtpe_req('delete', "delete", { 'from-tag' => ft() }); -($sock_a, $sock_b) = new_call([qw(198.51.100.1 3356)], [qw(198.51.100.3 3358)]); +new_call(); -($port_a, undef, $srtp_key_a) = offer('non-OSRTP offer with offer flag and protocol, accept', - { ICE => 'remove', replace => ['origin'], DTLS => 'off', OSRTP => ['offer'], - 'transport protocol' => 'RTP/AVP'}, < 'remove', + }, < 'remove', replace => ['origin'], DTLS => 'off', }, < 'remove', + }, < $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_80}, - key => 'Kl3GFJ5Gqz5x07xYkoyHODkVkSpiplZnXsQIw+Q7', -}; -$srtp_ctx_b = { - cs => $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_80}, - key => $srtp_key_a, -}; - -snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 160)); -srtp_rcv($sock_b, $port_a, rtpm(0, 1000, 3000, 0x1234, "\x00" x 160), $srtp_ctx_b); -srtp_snd($sock_b, $port_a, rtp(0, 2000, 4000, 0x3456, "\x00" x 160), $srtp_ctx_a); -rcv($sock_a, $port_b, rtpm(0, 2000, 4000, 0x3456, "\x00" x 160)); - - - - - - -($sock_a, $sock_b) = new_call([qw(198.51.100.1 3340)], [qw(198.51.100.3 3342)]); - -($port_a, undef, $srtp_key_a) = offer('non-OSRTP offer with offer flag, reject', - { ICE => 'remove', replace => ['origin'], DTLS => 'off', OSRTP => ['offer'] }, < 'remove', 'T.38' => [ 'decode' ], + }, < 'remove', replace => ['origin'], DTLS => 'off', }, < 'remove' }, < ft() }); -# MSRP (GH 959) new_call(); -offer('gh 959 media c=', { ICE => 'remove', }, < 'remove', + }, < 'remove', + }, < 'remove', 'T.38' => [ 'force' ], + }, < 'remove', }, < 'remove', + }, < ft() }); - - -# SDES key lifetime - new_call(); -offer('gh 966', { ICE => 'remove', 'transport-protocol' => 'RTP/SAVP', SDES => ['lifetime'], - DTLS => 'off' }, < 'remove', + }, < 'remove', codec => { mask => ['full'], transcode => ['PCMA','telephone-event'] } }, < 'remove', + }, < 'remove', }, < 'remove', 'T.38' => [ 'decode' ], + }, < 'remove' }, < ft() }); -new_call(); +new_call; -offer('gh 963 w mask all', { ICE => 'remove', codec => { mask => ['all'], transcode => ['PCMA','telephone-event'] } }, < 'remove', 'T.38' => [ 'force', 'FEC' ], + }, < 'remove', }, < ft() }); -# symmetric-codec flag (GH 953) +# github issue 850 -new_call(); +new_call; -offer('gh 953 w/o flag', { ICE => 'remove', codec => { transcode => ['G722'] } }, < 'force-relay', flags => [qw(SDES-off)], 'transport-protocol' => 'UDP/TLS/RTP/SAVPF', + 'rtcp-mux' => [qw(accept offer)], 'via-branch' => 'z9hG4bK9463.af303705.113', + }, < 'remove', }, < 'force-relay', flags => [qw(SDES-off)], 'transport-protocol' => 'UDP/TLS/RTP/SAVPF', + 'rtcp-mux' => [qw(accept offer)], 'via-branch' => 'z9hG4bK9463.af303705.113', + }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', flags => ['symmetric codecs'] }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', flags => ['symmetric codecs'] }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', }, < 'remove', codec => { transcode => ['G722'] } }, < 'remove', flags => ['symmetric codecs'] }, < [ 'decode' ], ICE => 'remove', - }, < ft() }); - - - - - - -new_call(); - -offer('T.38 forward re-invite', { ICE => 'remove', - }, < 'remove', - }, < 'remove', 'T.38' => [ 'force' ], - }, < 'remove', - }, < ft() }); - - - - -new_call(); - -offer('T.38 reverse re-invite', { ICE => 'remove', - }, < 'remove', - }, < 'remove', 'T.38' => [ 'decode' ], - }, < 'remove' }, < ft() }); - - - - - - -new_call(); - -offer('T.38 forward re-invite w/ unsupported codec', { ICE => 'remove', - }, < 'remove', - }, < 'remove', 'T.38' => [ 'force' ], - }, < 'remove', - }, < ft() }); - - - - -new_call(); - -offer('T.38 reverse re-invite w/ unsupported codec', { ICE => 'remove', - }, < 'remove', - }, < 'remove', 'T.38' => [ 'decode' ], - }, < 'remove' }, < ft() }); - - - -new_call; - -offer('T.38 FEC invite', { ICE => 'remove', 'T.38' => [ 'force', 'FEC' ], - }, < ft() }); - - - - - -# github issue 850 - -new_call; - -@ret1 = offer('gh 850', - { - ICE => 'force-relay', flags => [qw(SDES-off)], 'transport-protocol' => 'UDP/TLS/RTP/SAVPF', - 'rtcp-mux' => [qw(accept offer)], 'via-branch' => 'z9hG4bK9463.af303705.113', - }, < 'force-relay', flags => [qw(SDES-off)], 'transport-protocol' => 'UDP/TLS/RTP/SAVPF', - 'rtcp-mux' => [qw(accept offer)], 'via-branch' => 'z9hG4bK9463.af303705.113', - }, < 'remove', replace => ['origin'], codec => { transcode => ['PCMA'] } }, < 'remove', replace => ['origin'] }, < 'remove', replace => ['origin'], codec => { transcode => ['PCMA'] } }, < 'remove', replace => ['origin'] }, < 'remove', replace => ['origin'], flags => ['pad crypto'], DTLS => 'off' }, < 'remove', replace => ['origin'], flags => ['pad crypto'], DTLS => 'off' }, < $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_80}, - key => 'IDdiM2QzOWYzMjA2YzkwZWIxY2NmOWVhOTc4MjE1', -}; -$srtp_ctx_b = { - cs => $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_80}, - key => 'Qk0TvVeyfqfjFd/YebnyyklqSEhJntpVKV1KAhHa', -}; - -srtp_snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 160), $srtp_ctx_a); -srtp_rcv($sock_b, $port_a, rtpm(0, 1000, 3000, 0x1234, "\x00" x 160), $srtp_ctx_a); -srtp_snd($sock_b, $port_a, rtp(0, 2000, 4000, 0x3456, "\x00" x 160), $srtp_ctx_b); -srtp_rcv($sock_a, $port_b, rtpm(0, 2000, 4000, 0x3456, "\x00" x 160), $srtp_ctx_b); - - -($sock_a, $sock_b) = new_call([qw(198.51.100.1 7310)], [qw(198.51.100.3 7312)]); - -($port_a) = offer('gh829', - { ICE => 'remove', replace => ['origin'], flags => ['pad crypto'], DTLS => 'off' }, < 'remove', replace => ['origin'], flags => ['pad crypto'], DTLS => 'off' }, < $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_80}, - key => 'IDdiM2QzOWYzMjA2YzkwZWIxY2NmOWVhOTc4MjE1', -}; -$srtp_ctx_b = { - cs => $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_80}, - key => 'Qk0TvVeyfqfjFd/YebnyyklqSEhJntpVKV1KAhHa', -}; - -srtp_snd($sock_a, $port_b, rtp(0, 1000, 3000, 0x1234, "\x00" x 160), $srtp_ctx_a); -srtp_rcv($sock_b, $port_a, rtpm(0, 1000, 3000, 0x1234, "\x00" x 160), $srtp_ctx_a); -srtp_snd($sock_b, $port_a, rtp(0, 2000, 4000, 0x3456, "\x00" x 160), $srtp_ctx_b); -srtp_rcv($sock_a, $port_b, rtpm(0, 2000, 4000, 0x3456, "\x00" x 160), $srtp_ctx_b); - - -# DTMF injection -# -# no transcoding, RFC payload type present - -($sock_a, $sock_b) = new_call([qw(198.51.100.1 6010)], [qw(198.51.100.3 6012)]); - -($port_a) = offer('no transcoding, RFC payload type present', - { ICE => 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < ft(), code => '0', volume => 10, duration => 100 }); - -snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96 | 0x80, 1002, 3320, $ssrc, "\x00\x0a\x00\xa0")); -snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1003, 3320, $ssrc, "\x00\x0a\x01\x40")); -snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1004, 3320, $ssrc, "\x00\x0a\x01\xe0")); -snd($sock_a, $port_b, rtp(0, 1005, 3800, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1005, 3320, $ssrc, "\x00\x0a\x02\x80")); -snd($sock_a, $port_b, rtp(0, 1006, 3960, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1006, 3320, $ssrc, "\x00\x0a\x03\x20")); -snd($sock_a, $port_b, rtp(0, 1007, 4120, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1007, 3320, $ssrc, "\x00\x8a\x03\xc0")); -rcv($sock_b, $port_a, rtpm(96, 1008, 3320, $ssrc, "\x00\x8a\x03\xc0")); -rcv($sock_b, $port_a, rtpm(96, 1009, 3320, $ssrc, "\x00\x8a\x03\xc0")); -snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1010, 4280, $ssrc, "\x00" x 160)); - - - -snd($sock_b, $port_a, rtp(0, 4000, 8000, 0x6543, "\x00" x 160)); -($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 8000, -1, "\x00" x 160)); -snd($sock_b, $port_a, rtp(0, 4001, 8160, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4001, 8160, $ssrc, "\x00" x 160)); - -$resp = rtpe_req('play DTMF', 'inject DTMF towards A', - { 'from-tag' => tt(), code => '*', volume => 10, duration => 100 }); - -snd($sock_b, $port_a, rtp(0, 4002, 8320, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(96 | 0x80, 4002, 8320, $ssrc, "\x0a\x0a\x00\xa0")); -snd($sock_b, $port_a, rtp(0, 4003, 8480, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(96, 4003, 8320, $ssrc, "\x0a\x0a\x01\x40")); -snd($sock_b, $port_a, rtp(0, 4004, 8640, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(96, 4004, 8320, $ssrc, "\x0a\x0a\x01\xe0")); -snd($sock_b, $port_a, rtp(0, 4005, 8800, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(96, 4005, 8320, $ssrc, "\x0a\x0a\x02\x80")); -snd($sock_b, $port_a, rtp(0, 4006, 8960, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(96, 4006, 8320, $ssrc, "\x0a\x0a\x03\x20")); -snd($sock_b, $port_a, rtp(0, 4007, 9120, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(96, 4007, 8320, $ssrc, "\x0a\x8a\x03\xc0")); -rcv($sock_a, $port_b, rtpm(96, 4008, 8320, $ssrc, "\x0a\x8a\x03\xc0")); -rcv($sock_a, $port_b, rtpm(96, 4009, 8320, $ssrc, "\x0a\x8a\x03\xc0")); -snd($sock_b, $port_a, rtp(0, 4008, 9280, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4010, 9280, $ssrc, "\x00" x 160)); - - - - - -# transcoding, RFC payload type present on both sides - -($sock_a, $sock_b) = new_call([qw(198.51.100.1 6110)], [qw(198.51.100.3 6112)]); - -($port_a) = offer('transcoding, RFC payload type present on both sides', - { ICE => 'remove', replace => ['origin'], flags => ['inject DTMF'], - codec => { transcode => ['PCMA'] }}, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < ft(), code => '0', volume => 10, duration => 100 }); - -snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96 | 0x80, 1002, 3320, $ssrc, "\x00\x0a\x00\xa0")); -snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1003, 3320, $ssrc, "\x00\x0a\x01\x40")); -snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1004, 3320, $ssrc, "\x00\x0a\x01\xe0")); -snd($sock_a, $port_b, rtp(0, 1005, 3800, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1005, 3320, $ssrc, "\x00\x0a\x02\x80")); -snd($sock_a, $port_b, rtp(0, 1006, 3960, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1006, 3320, $ssrc, "\x00\x0a\x03\x20")); -snd($sock_a, $port_b, rtp(0, 1007, 4120, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1007, 3320, $ssrc, "\x00\x8a\x03\xc0")); -rcv($sock_b, $port_a, rtpm(96, 1008, 3320, $ssrc, "\x00\x8a\x03\xc0")); -rcv($sock_b, $port_a, rtpm(96, 1009, 3320, $ssrc, "\x00\x8a\x03\xc0")); -snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1010, 4280, $ssrc, "\x2a" x 160)); - - - -snd($sock_b, $port_a, rtp(8, 4000, 8000, 0x6543, "\x2a" x 160)); -($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 8000, -1, "\x00" x 160)); -snd($sock_b, $port_a, rtp(8, 4001, 8160, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4001, 8160, $ssrc, "\x00" x 160)); - -$resp = rtpe_req('play DTMF', 'inject DTMF towards A', - { 'from-tag' => tt(), code => '#', volume => -10, duration => 100 }); - -snd($sock_b, $port_a, rtp(8, 4002, 8320, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(96 | 0x80, 4002, 8320, $ssrc, "\x0b\x0a\x00\xa0")); -snd($sock_b, $port_a, rtp(8, 4003, 8480, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(96, 4003, 8320, $ssrc, "\x0b\x0a\x01\x40")); -snd($sock_b, $port_a, rtp(8, 4004, 8640, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(96, 4004, 8320, $ssrc, "\x0b\x0a\x01\xe0")); -snd($sock_b, $port_a, rtp(8, 4005, 8800, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(96, 4005, 8320, $ssrc, "\x0b\x0a\x02\x80")); -snd($sock_b, $port_a, rtp(8, 4006, 8960, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(96, 4006, 8320, $ssrc, "\x0b\x0a\x03\x20")); -snd($sock_b, $port_a, rtp(8, 4007, 9120, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(96, 4007, 8320, $ssrc, "\x0b\x8a\x03\xc0")); -rcv($sock_a, $port_b, rtpm(96, 4008, 8320, $ssrc, "\x0b\x8a\x03\xc0")); -rcv($sock_a, $port_b, rtpm(96, 4009, 8320, $ssrc, "\x0b\x8a\x03\xc0")); -snd($sock_b, $port_a, rtp(8, 4008, 9280, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4010, 9280, $ssrc, "\x00" x 160)); - - - -# no transcoding, no RFC payload type present - -($sock_a, $sock_b) = new_call([qw(198.51.100.1 6014)], [qw(198.51.100.3 6016)]); - -($port_a) = offer('no transcoding, no RFC payload type present', - { ICE => 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < ft(), code => 'C', volume => 5, duration => 120, pause => 110 }); - -snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1002, 3320, $ssrc, "\xff\x93\x94\xbc\x2e\x56\xbf\x2b\x13\x1b\xa7\x8e\x98\x47\x25\x41\xe2\x24\x16\x2b\x99\x8e\x9f\x28\x1e\x3d\x5b\x23\x1c\xdf\x92\x8f\xb6\x1c\x1c\x40\x5d\x26\x25\xaa\x8f\x95\x3b\x15\x1d\x5e\xde\x2c\x38\x9d\x8f\x9e\x1f\x11\x20\xc0\xc1\x37\xdd\x99\x92\xb7\x15\x10\x2c\xac\xb5\x49\xb8\x97\x99\x37\x0f\x13\x58\xa0\xae\x67\xae\x99\xa4\x1f\x0d\x1a\xae\x9b\xad\x7b\xad\x9d\xbf\x16\x0e\x27\x9d\x98\xb0\x55\xb1\xa6\x3a\x11\x11\x63\x95\x98\xbf\x3e\xbb\xb4\x26\x10\x1a\xa9\x90\x9a\x4e\x30\xce\xd4\x1e\x12\x29\x99\x8e\xa1\x2d\x29\x6d\x4b\x1c\x18\xef\x91\x8f\xb6\x1f\x24\x57\x3e\x1d\x20\xa9\x8e\x95\x3e\x19\x23\x67\x3e\x21\x31\x9c\x8e\x9e\x22\x14\x26\xcd\x4a")); -snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1003, 3480, $ssrc, "\x2a\xdf\x96\x90\xb5\x17\x13\x2f\xb6\xf5\x36\xb1\x93\x96\x39\x10\x15\x55\xaa\xc8\x4c\xa7\x95\xa0\x1f\x0e\x1b\xb4\xa1\xbd\xed\xa4\x99\xbb\x15\x0e\x27\xa0\x9d\xbd\xda\xa4\x9f\x39\x10\x11\x58\x98\x9c\xc8\xf9\xa9\xac\x23\x0e\x19\xab\x92\x9e\x59\x4c\xb0\xca\x1b\x10\x27\x9a\x90\xa5\x35\x3a\xbe\x43\x18\x15\x6c\x92\x91\xb7\x26\x30\xd6\x32\x18\x1d\xa9\x8e\x96\x44\x1d\x2d\xfc\x2e\x1b\x2d\x9a\x8d\x9e\x25\x19\x2d\xe7\x2f\x20\xea\x94\x8f\xb3\x19\x17\x36\xc8\x36\x2c\xae\x90\x95\x3b\x12\x18\x55\xb7\x43\x3e\xa1\x91\x9e\x1f\x0f\x1d\xba\xac\x64\xe8\x9d\x95\xb7\x15\x0e\x29\xa6\xa6\xda\xc3\x9d\x9b\x39\x0f\x11\x51\x9c\xa2\xd8\xbe\x9f\xa7\x21\x0e\x18\xad")); -snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1004, 3640, $ssrc, "\x96\xa3\x68\xc4\xa5\xc2\x19\x0e\x26\x9c\x93\xa9\x3f\xdb\xae\x3e\x14\x12\x5b\x93\x93\xb9\x2e\x51\xbe\x2c\x14\x1b\xa9\x8f\x97\x4c\x25\x3f\xde\x25\x16\x2a\x9a\x8e\x9e\x29\x1e\x3b\x5e\x24\x1b\x7b\x92\x8f\xb2\x1c\x1c\x3e\x61\x27\x25\xac\x8f\x94\x3e\x15\x1c\x59\xdb\x2d\x37\x9e\x8f\x9d\x20\x11\x1f\xc2\xbf\x38\xea\x99\x92\xb4\x16\x10\x2b\xad\xb4\x49\xba\x98\x98\x3a\x0f\x12\x4e\xa1\xad\x68\xaf\x99\xa3\x20\x0d\x19\xb0\x9b\xac\x7b\xae\x9d\xbc\x17\x0e\x25\x9e\x98\xaf\x55\xb2\xa6\x3d\x12\x11\x52\x96\x97\xbd\x3e\xbc\xb3\x28\x10\x19\xab\x90\x9a\x54\x2f\xd0\xcf\x1f\x12\x27\x9a\x8e\xa0\x2e\x28\x66\x4e\x1d\x18\x62\x92\x8f\xb2\x20\x23\x53\x3f\x1d\x1f")); -snd($sock_a, $port_b, rtp(0, 1005, 3800, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1005, 3800, $ssrc, "\xab\x8e\x94\x44\x19\x22\x61\x40\x21\x2f\x9c\x8e\x9d\x23\x14\x25\xce\x4d\x2a\xf7\x96\x8f\xb1\x18\x13\x2e\xb7\xe8\x36\xb3\x94\x96\x3c\x10\x15\x4d\xaa\xc5\x4b\xa8\x95\x9f\x20\x0e\x1a\xb6\xa0\xbc\xf5\xa4\x99\xb8\x16\x0e\x26\xa1\x9d\xbb\xdd\xa5\x9f\x3c\x10\x10\x4c\x99\x9b\xc5\x78\xaa\xac\x24\x0f\x18\xac\x93\x9d\x5f\x4a\xb1\xc7\x1c\x0f\x25\x9b\x90\xa3\x36\x39\xbf\x47\x18\x14\x56\x92\x90\xb4\x27\x2f\xd7\x34\x18\x1c\xab\x8e\x95\x4b\x1d\x2c\xfe\x2f\x1b\x2c\x9b\x8d\x9d\x27\x19\x2c\xe7\x30\x20\x6d\x94\x8f\xaf\x1a\x17\x34\xc8\x37\x2b\xaf\x91\x94\x3f\x12\x18\x4e\xb6\x45\x3d\xa3\x91\x9e\x20\x0f\x1c\xbc\xab\x6c\xf5\x9e\x95\xb3\x16\x0e\x27\xa7\xa5")); -snd($sock_a, $port_b, rtp(0, 1006, 3960, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1006, 3960, $ssrc, "\xd6\xc6\x9d\x9b\x3d\x0f\x11\x49\x9c\xa1\xd4\xbf\x9f\xa6\x22\x0e\x18\xaf\x96\xa2\x6e\xc6\xa5\xbe\x19\x0e\x24\x9d\x93\xa8\x40\xe1\xae\x42\x15\x12\x4e\x94\x93\xb7\x2e\x4e\xbe\x2d\x14\x1a\xab\x8f\x97\x52\x25\x3e\xdc\x26\x16\x28\x9b\x8e\x9e\x2b\x1e\x3a\x61\x25\x1b\x5d\x93\x8f\xaf\x1d\x1c\x3d\x67\x27\x24\xad\x8f\x93\x45\x15\x1c\x53\xd7\x2d\x35\x9f\x8f\x9c\x22\x11\x1f\xc5\xbe\x38\x7a\x9a\x91\xb0\x17\x10\x29\xad\xb3\x4a\xbc\x98\x98\x3e\x10\x12\x48\xa1\xad\x6a\xb1\x9a\xa1\x21\x0e\x18\xb3\x9b\xab\x7d\xaf\x9d\xb9\x18\x0e\x23\x9f\x97\xae\x55\xb4\xa5\x40\x12\x10\x49\x96\x97\xbb\x3d\xbd\xb2\x29\x10\x18\xac\x90\x99\x5d\x2f\xd4\xcd\x1f\x12\x25\x9b")); -snd($sock_a, $port_b, rtp(0, 1007, 4120, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1007, 4120, $ssrc, "\x8e\x9f\x2f\x28\x5f\x51\x1d\x17\x52\x92\x8f\xaf\x20\x22\x50\x42\x1e\x1f\xad\x8e\x93\x4b\x19\x21\x5d\x42\x22\x2e\x9d\x8e\x9c\x25\x14\x24\xd0\x4f\x2a\x68\x97\x8f\xae\x18\x12\x2c\xb7\xdf\x36\xb6\x94\x95\x41\x11\x14\x48\xaa\xc3\x4a\xaa\x95\x9e\x21\x0e\x19\xb8\xa0\xba\xfe\xa5\x99\xb4\x17\x0e\x24\xa2\x9c\xba\xe0\xa6\x9e\x40\x10\x10\x45\x99\x9b\xc2\x6d\xaa\xab\x26\x0f\x17\xae\x93\x9c\x6a\x48\xb2\xc3\x1c\x0f\x23\x9c\x90\xa2\x37\x38\xbf\x4b\x19\x14\x4b\x93\x90\xb1\x27\x2e\xd8\x36\x19\x1c\xad\x8e\x94\x52\x1d\x2b\x7d\x30\x1b\x2a\x9c\x8d\x9c\x28\x19\x2b\xe7\x31\x20\x5a\x95\x8f\xad\x1a\x16\x32\xc8\x39\x2b\xb2\x91\x94\x46\x13\x17\x4a\xb6\x48\x3c")); -# pause -snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1008, 4280, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1009, 4440, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1009, 4440, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1010, 4600, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1010, 4600, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1011, 4760, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1011, 4760, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1012, 4920, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1012, 4920, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1013, 5080, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1013, 5080, $ssrc, "\xff" x 80 . "\x00" x 80)); - - - -snd($sock_b, $port_a, rtp(0, 4000, 8000, 0x6543, "\x00" x 160)); -($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 8000, -1, "\x00" x 160)); -snd($sock_b, $port_a, rtp(0, 4001, 8160, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4001, 8160, $ssrc, "\x00" x 160)); +a=rtpmap:0 PCMU/8000 +a=rtpmap:8 PCMA/8000 +a=rtpmap:106 CN/32000 +a=rtpmap:105 CN/16000 +a=rtpmap:13 CN/8000 +a=rtpmap:110 telephone-event/48000 +a=rtpmap:112 telephone-event/32000 +a=rtpmap:113 telephone-event/16000 +a=rtpmap:126 telephone-event/8000 +a=sendrecv +a=rtcp:PORT +a=rtcp-mux +a=candidate:ICEBASE 1 UDP 16777215 203.0.113.1 PORT typ relay raddr 203.0.113.1 rport PORT +a=candidate:ICEBASE 1 UDP 16776959 2001:db8:4321::1 PORT typ relay raddr 2001:db8:4321::1 rport PORT +SDP -$resp = rtpe_req('play DTMF', 'inject DTMF towards A', - { 'from-tag' => tt(), code => '4', volume => 3, duration => 150, pause => 100 }); +is $ret1[2], $ret1[3], 'rtp rport 1'; +is $ret1[5], $ret1[6], 'rtp rport 2'; -snd($sock_b, $port_a, rtp(0, 4002, 8320, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4002, 8320, $ssrc, "\xff\x90\x8a\x93\xd9\x1b\x18\x27\x65\xe5\x33\x29\x4c\x9e\x8f\x91\xb8\x15\x09\x0d\x32\x98\x8e\x96\xbb\x2c\x2b\x4c\xd8\x34\x1c\x18\x2e\x9d\x8c\x8c\xa5\x1a\x0b\x0d\x27\xa3\x97\x9e\xbd\x4f\xc4\xaa\xb2\x2c\x12\x0e\x1e\xa1\x8b\x8a\x9c\x25\x0e\x10\x25\xb7\xa7\xb7\x5e\xcb\xa2\x98\x9f\x30\x0f\x0a\x16\xae\x8d\x8a\x98\x3a\x18\x19\x2c\xdd\xfd\x30\x2b\xce\x99\x8e\x95\x4c\x0f\x09\x10\xdf\x93\x8e\x9a\xec\x28\x2c\x56\xee\x2d\x1a\x1a\x48\x97\x8b\x8e\xba\x14\x0a\x0f\x39\x9d\x96\xa1\xcd\x4e\xbe\xab\xbe\x23\x10\x10\x2b\x99\x8a\x8c\xa7\x1b\x0d\x12\x2f\xad\xa7\xbc\x5e\xbd\x9f\x99\xa8\x23\x0d\x0b\x1d\x9f\x8b\x8c\x9f\x29\x16\x1b\x34\xcd\x60\x2f\x2f\xb6\x96")); -snd($sock_b, $port_a, rtp(0, 4003, 8480, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4003, 8480, $ssrc, "\x8e\x9b\x2b\x0c\x09\x17\xae\x8f\x8e\x9e\x3f\x25\x2e\x65\x5c\x28\x1a\x1e\xc2\x92\x8a\x92\x44\x0f\x0a\x14\xd6\x99\x97\xa6\x7c\x4e\xba\xad\xe5\x1d\x0f\x13\x49\x92\x89\x8e\xbe\x15\x0d\x16\x43\xa8\xa7\xc1\x66\xb5\x9d\x9a\xb6\x1b\x0c\x0d\x2b\x98\x8a\x8d\xab\x1f\x15\x1d\x3f\xc7\x52\x2e\x39\xaa\x93\x8f\xa3\x1e\x0b\x0b\x1e\x9f\x8d\x8f\xa7\x30\x23\x31\x7c\x4a\x24\x1a\x24\xac\x8e\x8b\x99\x28\x0c\x0a\x1a\xb0\x96\x98\xac\x4f\x53\xb7\xaf\x44\x19\x0f\x18\xba\x8e\x89\x93\x3f\x10\x0d\x1a\xd5\xa3\xa8\xca\xf9\xae\x9c\x9d\xec\x16\x0b\x10\x4e\x91\x89\x90\xc6\x1a\x14\x20\x55\xc3\x4a\x2f\x49\xa2\x91\x92\xb2\x17\x09\x0c\x2d\x99\x8d\x92\xb3\x29\x23\x36\xf2")); -snd($sock_b, $port_a, rtp(0, 4004, 8640, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4004, 8640, $ssrc, "\x3e\x20\x1b\x2d\xa0\x8d\x8c\xa1\x1c\x0a\x0c\x22\xa3\x94\x9a\xb5\x44\x5c\xb5\xb6\x32\x16\x0f\x1e\xa6\x8c\x8a\x99\x28\x0e\x0e\x20\xb7\xa1\xab\xd4\xdb\xaa\x9c\xa1\x38\x11\x0b\x15\xb5\x8d\x8a\x96\x3f\x16\x15\x26\xdd\xc2\x43\x31\xdf\x9d\x90\x96\x6d\x11\x09\x0f\x5a\x93\x8c\x97\xd2\x23\x23\x3b\xf6\x37\x1f\x1d\x40\x9a\x8c\x8e\xb2\x15\x09\x0e\x31\x9c\x93\x9c\xc2\x3e\x74\xb4\xbf\x29\x14\x11\x29\x9b\x8a\x8b\xa3\x1c\x0d\x0f\x2a\xab\x9f\xad\xe0\xcc\xa6\x9c\xa9\x28\x0e\x0c\x1c\xa2\x8b\x8b\x9c\x2a\x14\x17\x2c\xc6\xc4\x3e\x36\xbd\x99\x90\x9b\x30\x0d\x09\x15\xb3\x8f\x8d\x9b\x42\x1f\x25\x42\x70\x30\x1e\x1f\xcf\x95\x8b\x92\x58\x0f\x09\x12\x6f\x98\x93")); -snd($sock_b, $port_a, rtp(0, 4005, 8800, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4005, 8800, $ssrc, "\x9f\xe5\x3b\xe2\xb5\xd9\x21\x12\x14\x3e\x95\x89\x8d\xb6\x16\x0c\x13\x3a\xa4\x9f\xb1\xf1\xc0\xa3\x9d\xb4\x1e\x0d\x0d\x27\x99\x8a\x8c\xa7\x1f\x12\x19\x37\xbc\xc8\x3c\x3c\xaf\x97\x91\xa2\x21\x0b\x0a\x1c\xa2\x8d\x8e\xa2\x2f\x1e\x28\x4c\x5d\x2c\x1e\x25\xb0\x90\x8c\x98\x2c\x0c\x0a\x18\xb4\x94\x94\xa6\x4d\x3a\xd4\xb8\x4f\x1d\x11\x18\xc5\x8f\x89\x91\x4d\x10\x0c\x17\xec\x9f\xa0\xb8\xff\xba\xa1\x9f\xd3\x19\x0c\x0f\x3f\x92\x89\x8f\xbb\x19\x11\x1c\x48\xb8\xce\x3b\x4a\xa8\x95\x93\xaf\x19\x0a\x0c\x29\x99\x8c\x8f\xad\x27\x1d\x2b\x59\x4f\x29\x1e\x2d\xa5\x8e\x8d\x9f\x1e\x0b\x0b\x1e\xa4\x91\x96\xad\x3e\x3b\xcc\xbc\x3a\x1a\x12\x1e\xaa\x8d\x8a\x98\x2b")); -snd($sock_b, $port_a, rtp(0, 4006, 8960, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4006, 8960, $ssrc, "\x0e\x0c\x1d\xb8\x9d\xa2\xbe\xf9\xb4\xa0\xa3\x3f\x14\x0c\x14\xbd\x8e\x89\x93\x49\x15\x12\x1f\xe7\xb5\xd9\x3c\x7c\xa1\x93\x97\xd5\x13\x09\x0e\x45\x93\x8b\x93\xc4\x20\x1d\x2e\x6b\x46\x26\x1f\x3d\x9d\x8d\x8e\xae\x17\x09\x0d\x2c\x9c\x90\x98\xba\x36\x3d\xc7\xc4\x2e\x17\x13\x27\x9e\x8b\x8b\x9f\x1e\x0c\x0e\x25\xaa\x9c\xa5\xc8\xe8\xae\xa0\xaa\x2d\x10\x0c\x1b\xa6\x8c\x8a\x9a\x2c\x12\x13\x27\xc3\xb3\xed\x3e\xc8\x9d\x93\x9b\x38\x0f\x09\x13\xba\x8f\x8b\x98\x4a\x1d\x1e\x34\xf9\x3e\x24\x23\xea\x98\x8c\x92\xdf\x10\x09\x0f\x4d\x97\x90\x9c\xd2\x31\x3f\xc5\xd6\x28\x16\x16\x39\x97\x8a\x8d\xaf\x17\x0b\x10\x32\xa2\x9b\xa8\xd6\xd9\xac\xa1\xb3\x22\x0e\x0e")); -snd($sock_b, $port_a, rtp(0, 4007, 9120, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4007, 9120, $ssrc, "\x24\x9b\x8a\x8b\xa2\x1f\x10\x15\x2f\xb8\xb4\x68\x43\xb8\x9a\x94\xa1\x25\x0c\x0a\x1a\xa5\x8d\x8c\x9e\x30\x1b\x1f\x3c\xee\x38\x23\x28\xb8\x93\x8d\x97\x31\x0d\x09\x15\xb9\x93\x90\xa0\x4f\x2f\x46\xc4\x5e\x21\x15\x19\xd7\x91\x89\x90\x7b\x10\x0b\x14\x5b\x9d\x9c\xad\xed\xcd\xa9\xa3\xca\x1c\x0d\x10\x38\x94\x89\x8e\xb3\x19\x0f\x18\x3e\xb0\xb5\x59\x4d\xae\x98\x95\xad\x1c\x0b\x0c\x25\x9b\x8b\x8e\xa9\x26\x1a\x22\x46\xf5\x33\x23\x2e\xaa\x90\x8d\x9e\x21\x0b\x0a\x1c\xa6\x90\x92\xa8\x3b\x2e\x4d\xc7\x43\x1e\x15\x1e\xaf\x8e\x8a\x96\x2e\x0e\x0b\x1a\xbb\x9b\x9d\xb2\x68\xc5\xa8\xa7\x4c\x17\x0d\x14\xcb\x8f\x89\x91\x5e\x14\x0f\x1c\x6e\xad\xb8\x52\x68\xa8")); -snd($sock_b, $port_a, rtp(0, 4008, 9280, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4008, 9280, $ssrc, "\x97\x98\xc7\x16\x0a\x0e\x3a\x94\x8a\x90\xbb\x1e\x1a\x27\x56\x6f\x2f\x25\x3b\xa0\x8e\x8f\xaa\x19\x09\x0c\x28\x9c\x8f\x95\xb2\x31\x2e\x59\xcc\x37\x1b\x16\x26\xa1\x8c\x8b\x9d\x1f\x0c\x0c\x20\xab\x99\x9e\xbb\x5d\xbe\xa7\xac\x32\x13\x0d\x1a\xab\x8c\x89\x97\x2e\x10\x10\x21\xc3\xab\xbc\x4f\xd4\xa2\x96\x9c\x3f\x10\x0a\x12\xc4\x8f\x8a\x95\x57\x1b\x1a\x2b\xfd\x5d\x2d\x27\x62\x9b\x8e\x92\xc9\x12\x09\x0e\x3f\x97\x8e\x98\xc6\x2c\x2f\x6b\xd9\x2e\x1a\x18\x34\x9a\x8b\x8d\xab\x18\x0a\x0e\x2d\xa1\x98\xa1\xc7\x5b\xb9\xa7\xb4\x27\x10\x0e\x22\x9d\x8a\x8b\x9f\x20\x0e\x12\x2a\xb4\xaa\xc0\x50\xc0\x9e\x97\xa1\x2a\x0e\x0a\x19\xa8\x8c\x8b\x9b\x31\x18\x1b\x31")); -snd($sock_b, $port_a, rtp(0, 4009, 9440, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4009, 9440, $ssrc, "\xda\x50\x2c\x2b\xc0\x97\x8e\x97\x39\x0e\x09\x13\xbf\x92\x8e\x9c\x57\x29\x31\xef\x72\x28\x19\x1b\x6d\x94\x8a\x8f\xce\x11\x0a\x11\x48\x9c\x98\xa5\xdc\x5e\xb5\xa9\xc6\x1f\x0f\x10\x31\x96\x89\x8d\xad\x19\x0e\x15\x37\xac\xaa\xc8\x57\xb7\x9c\x98\xac\x1e\x0c\x0c\x21\x9c\x8b\x8d\xa4\x25\x17\x1d\x3b\xcf\x48\x2b\x30\xae\x93\x8e" . "\xff" x 80)); -# pause -snd($sock_b, $port_a, rtp(0, 4010, 9600, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4010, 9600, $ssrc, "\xff" x 160)); -snd($sock_b, $port_a, rtp(0, 4011, 9760, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4011, 9760, $ssrc, "\xff" x 160)); -snd($sock_b, $port_a, rtp(0, 4012, 9920, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4012, 9920, $ssrc, "\xff" x 160)); -snd($sock_b, $port_a, rtp(0, 4013, 10080, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4013, 10080, $ssrc, "\xff" x 160)); -snd($sock_b, $port_a, rtp(0, 4014, 10240, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4014, 10240, $ssrc, "\xff" x 80 . "\x00" x 80)); +if (0) { -# transcoding, no RFC payload type present +# github issue 854 -($sock_a, $sock_b) = new_call([qw(198.51.100.1 6018)], [qw(198.51.100.3 6020)]); +($sock_a, $sock_b) = new_call([qw(198.51.100.1 7326)], [qw(198.51.100.3 7328)]); -($port_a) = offer('transcoding, no RFC payload type present', - { ICE => 'remove', replace => ['origin'], flags => ['inject DTMF'], - codec => { transcode => ['PCMA'] } }, < 'remove', replace => ['origin'], codec => { transcode => ['PCMA'] } }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'remove', replace => ['origin'] }, < ft(), code => 'C', volume => 5, duration => 120 }); - -snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1002, 3320, $ssrc, "\xd5\xb9\xbe\x97\x05\x70\xea\x01\x3e\x31\x82\xa5\xb2\x63\x0f\x69\xc1\x0f\x3d\x06\xb3\xa4\x8a\x03\x35\x14\x75\x0e\x36\xcc\xb8\xa5\x9d\x36\x36\x68\x49\x0d\x0c\x81\xa5\xbf\x16\x3f\x37\x4f\xcf\x07\x13\xb4\xa5\xb4\x0a\x3b\x0b\xeb\xe9\x12\xc9\xb3\xb8\x92\x3c\x3a\x07\x87\x9c\x61\x93\xb2\xb3\x12\x25\x39\x76\x8b\x85\x5a\x85\xb3\x8e\x35\x24\x30\x85\xb1\x87\x57\x84\xb7\xeb\x3c\x24\x0d\xb4\xb2\x9b\x70\x98\x8c\x11\x3b\x38\x41\xbf\xb2\xeb\x15\x96\x9f\x0d\x3a\x30\x83\xba\xb1\x7b\x1b\xfa\xf2\x34\x39\x03\xb0\xa5\x88\x04\x03\x5f\x67\x37\x32\xdd\xb8\xba\x9d\x35\x0e\x71\x15\x37\x0a\x80\xa4\xbf\x15\x33\x09\x45\x15\x0b\x18\xb6\xa4\xb4\x08\x3f\x0d\xe5\x66")); -snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1003, 3480, $ssrc, "\x00\xcd\xbc\xba\x9c\x3d\x39\x1a\x9d\xd1\x1d\x98\xbe\xbd\x10\x3a\x3f\x73\x80\xe0\x64\x82\xbf\x8b\x35\x24\x31\x9f\x8b\x94\xdf\x8e\xb3\x96\x3c\x24\x02\x8b\xb7\x94\xf4\x8f\xb5\x10\x3a\x3b\x76\xb2\xb6\xe0\xd6\x80\x87\x09\x25\x33\x81\xb9\xb4\x74\x64\x9b\xe6\x31\x3a\x0d\xb1\xba\x8f\x1c\x11\x95\x6f\x32\x3f\x5e\xb8\xbb\x92\x0d\x1a\xf0\x19\x32\x37\x83\xa4\xbc\x6d\x37\x07\xd4\x04\x31\x07\xb1\xa4\xb4\x0c\x33\x04\xc5\x05\x0b\xd8\xbe\xa5\x9e\x30\x3d\x1d\xe0\x1d\x06\x84\xbb\xbf\x16\x38\x33\x73\x92\x6f\x15\x88\xbb\xb5\x35\x25\x37\x91\x86\x46\xda\xb7\xbf\x92\x3c\x25\x03\x8d\x8c\xf4\xef\xb7\xb6\x10\x25\x3b\x7f\xb6\x89\xf6\x95\xb5\x82\x0b\x24\x33\x84")); -snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1004, 3640, $ssrc, "\xbd\x8e\x5a\xec\x8c\xee\x33\x24\x0c\xb6\xbe\x80\x6b\xf5\x85\x6a\x3f\x39\x4a\xbe\xbe\x90\x05\x7f\x95\x06\x3e\x31\x80\xa5\xbd\x64\x0f\x6b\xcc\x0c\x3d\x00\xb0\xa4\xb5\x00\x34\x16\x4e\x0e\x36\x57\xb9\xa5\x99\x36\x36\x6a\x43\x0d\x0f\x86\xa5\xbe\x15\x3f\x36\x77\xf5\x07\x12\xb4\xa5\xb4\x0b\x3b\x0a\xee\xeb\x13\xd8\xb0\xb8\x9f\x3c\x3a\x01\x87\x9f\x66\x91\xb2\xb3\x11\x25\x39\x7a\x8b\x84\x5b\x9a\xb0\x89\x0a\x24\x33\x9b\xb1\x87\x54\x85\xb7\x97\x3d\x24\x0c\xb4\xb2\x9a\x73\x99\x8c\x14\x38\x3b\x7c\xbc\xbd\x94\x15\x97\x9e\x02\x3a\x33\x81\xba\xb0\x73\x1a\xfe\xf9\x35\x39\x02\xb1\xa4\x8a\x05\x03\x44\x7a\x37\x32\x40\xb8\xa5\x99\x0a\x0e\x72\x6b\x34\x35")); -snd($sock_a, $port_b, rtp(0, 1005, 3800, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1005, 3800, $ssrc, "\x81\xa4\xbe\x6c\x33\x08\x43\x68\x08\x1a\xb7\xa4\xb7\x0e\x3f\x0c\xfb\x65\x00\xd1\xbd\xba\x98\x32\x39\x04\x92\xdb\x1d\x9e\xbe\xbc\x17\x3a\x3f\x65\x80\xed\x67\x83\xbf\xb5\x0a\x24\x30\x9d\x8b\x97\xd0\x8f\xb3\x93\x3c\x24\x0c\x88\xb7\x96\xc9\x8c\xb5\x17\x3a\x3a\x64\xb3\xb6\xed\x56\x80\x86\x0f\x25\x32\x87\xb9\xb7\x4d\x66\x98\xe3\x36\x3a\x0c\xb1\xba\x8e\x1d\x10\xea\x63\x33\x3f\x70\xb9\xbb\x9f\x0d\x05\xf1\x1f\x33\x36\x81\xa4\xbf\x67\x34\x06\xd5\x05\x31\x06\xb6\xa4\xb7\x0d\x33\x07\xc5\x1a\x0a\x5f\xbe\xa5\x9a\x30\x3d\x1f\xe0\x12\x06\x9a\xbb\xbf\x6b\x39\x32\x7b\x9d\x62\x14\x89\xbb\xb4\x0b\x25\x36\x97\x86\x5e\xd1\xb4\xbf\x9e\x3c\x24\x0d\x82\x8c")); -snd($sock_a, $port_b, rtp(0, 1006, 3960, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1006, 3960, $ssrc, "\xf0\xe2\xb7\xb1\x14\x3a\x3b\x61\xb6\x88\xf3\xeb\xb5\x8d\x09\x24\x32\x85\xbd\x89\x5c\xe2\x8c\x95\x30\x24\x0e\xb7\xb9\x83\x68\xc3\x85\x6e\x3f\x38\x7a\xbe\xb9\x92\x05\x7a\x95\x07\x3e\x30\x86\xa5\xbd\x7c\x0f\x15\xcb\x0d\x3d\x03\xb1\xa4\xb4\x01\x34\x11\x40\x0f\x36\x48\xb9\xa5\x85\x37\x36\x14\x45\x02\x0f\x84\xa5\xbe\x6d\x3c\x36\x7d\xf1\x04\x1c\xb5\xa5\xb7\x09\x3b\x35\xed\xea\x13\x57\xb0\xb8\x9b\x3d\x3a\x00\x84\x9e\x66\x97\xb2\xb2\x15\x3a\x38\x60\x8b\x87\x58\x98\xb0\x88\x08\x24\x32\x9e\xb1\x86\x54\x9a\xb7\x90\x32\x24\x0e\xb5\xb2\x84\x73\x9f\x8c\x68\x38\x3b\x61\xbc\xbd\x96\x14\x94\x99\x03\x3b\x32\x87\xba\xb3\x48\x1a\xf2\xe5\x0a\x39\x0c\xb1")); -snd($sock_a, $port_b, rtp(0, 1007, 4120, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1007, 4120, $ssrc, "\xa4\xb5\x1a\x02\x4c\x7f\x37\x32\x7c\xb9\xa5\x9a\x0a\x09\x7e\x6e\x34\x35\x87\xa5\xbe\x67\x33\x0b\x48\x6e\x08\x05\xb7\xa4\xb6\x0f\x3f\x0e\xfe\x79\x00\x5a\xbd\xa5\x85\x32\x39\x07\x92\xcd\x1d\x9d\xbe\xbc\x69\x3b\x3e\x60\x80\xef\x66\x80\xbf\xb5\x08\x24\x30\x90\x8b\x91\xd5\x8c\xb3\x9f\x3d\x24\x0e\x89\xb7\x91\xc2\x8c\xb5\x68\x3b\x3a\x6d\xb3\xb1\xee\x5c\x81\x81\x0c\x25\x3d\x85\xb9\xb7\x58\x60\x99\xef\x37\x3a\x0e\xb6\xba\x89\x12\x13\xeb\x67\x33\x3e\x67\xb9\xba\x98\x02\x05\xf7\x1d\x33\x36\x87\xa4\xbe\x7c\x34\x01\x54\x1a\x31\x01\xb6\xa4\xb6\x03\x33\x06\xda\x18\x0a\x75\xbf\xa5\x84\x31\x3d\x19\xe0\x10\x01\x99\xbb\xbe\x62\x39\x3d\x66\x9d\x60\x17")); -# pause -snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1008, 4280, $ssrc, "\xd5" x 160)); -snd($sock_a, $port_b, rtp(0, 1009, 4440, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1009, 4440, $ssrc, "\xd5" x 160)); -snd($sock_a, $port_b, rtp(0, 1010, 4600, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1010, 4600, $ssrc, "\xd5" x 160)); -snd($sock_a, $port_b, rtp(0, 1011, 4760, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1011, 4760, $ssrc, "\xd5" x 160)); -snd($sock_a, $port_b, rtp(0, 1012, 4920, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1012, 4920, $ssrc, "\xd5" x 160)); -snd($sock_a, $port_b, rtp(0, 1013, 5080, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(8, 1013, 5080, $ssrc, "\x2a" x 160)); - - - - -snd($sock_b, $port_a, rtp(8, 4000, 8000, 0x6543, "\x2a" x 160)); -($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 8000, -1, "\x00" x 160)); -snd($sock_b, $port_a, rtp(8, 4001, 8160, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4001, 8160, $ssrc, "\x00" x 160)); - -$resp = rtpe_req('play DTMF', 'inject DTMF towards A', - { 'from-tag' => tt(), code => '4', volume => 3, duration => 150 }); - -snd($sock_b, $port_a, rtp(8, 4002, 8320, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4002, 8320, $ssrc, "\xff\x90\x8a\x93\xd9\x1b\x18\x27\x65\xe5\x33\x29\x4c\x9e\x8f\x91\xb8\x15\x09\x0d\x32\x98\x8e\x96\xbb\x2c\x2b\x4c\xd8\x34\x1c\x18\x2e\x9d\x8c\x8c\xa5\x1a\x0b\x0d\x27\xa3\x97\x9e\xbd\x4f\xc4\xaa\xb2\x2c\x12\x0e\x1e\xa1\x8b\x8a\x9c\x25\x0e\x10\x25\xb7\xa7\xb7\x5e\xcb\xa2\x98\x9f\x30\x0f\x0a\x16\xae\x8d\x8a\x98\x3a\x18\x19\x2c\xdd\xfd\x30\x2b\xce\x99\x8e\x95\x4c\x0f\x09\x10\xdf\x93\x8e\x9a\xec\x28\x2c\x56\xee\x2d\x1a\x1a\x48\x97\x8b\x8e\xba\x14\x0a\x0f\x39\x9d\x96\xa1\xcd\x4e\xbe\xab\xbe\x23\x10\x10\x2b\x99\x8a\x8c\xa7\x1b\x0d\x12\x2f\xad\xa7\xbc\x5e\xbd\x9f\x99\xa8\x23\x0d\x0b\x1d\x9f\x8b\x8c\x9f\x29\x16\x1b\x34\xcd\x60\x2f\x2f\xb6\x96")); -snd($sock_b, $port_a, rtp(8, 4003, 8480, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4003, 8480, $ssrc, "\x8e\x9b\x2b\x0c\x09\x17\xae\x8f\x8e\x9e\x3f\x25\x2e\x65\x5c\x28\x1a\x1e\xc2\x92\x8a\x92\x44\x0f\x0a\x14\xd6\x99\x97\xa6\x7c\x4e\xba\xad\xe5\x1d\x0f\x13\x49\x92\x89\x8e\xbe\x15\x0d\x16\x43\xa8\xa7\xc1\x66\xb5\x9d\x9a\xb6\x1b\x0c\x0d\x2b\x98\x8a\x8d\xab\x1f\x15\x1d\x3f\xc7\x52\x2e\x39\xaa\x93\x8f\xa3\x1e\x0b\x0b\x1e\x9f\x8d\x8f\xa7\x30\x23\x31\x7c\x4a\x24\x1a\x24\xac\x8e\x8b\x99\x28\x0c\x0a\x1a\xb0\x96\x98\xac\x4f\x53\xb7\xaf\x44\x19\x0f\x18\xba\x8e\x89\x93\x3f\x10\x0d\x1a\xd5\xa3\xa8\xca\xf9\xae\x9c\x9d\xec\x16\x0b\x10\x4e\x91\x89\x90\xc6\x1a\x14\x20\x55\xc3\x4a\x2f\x49\xa2\x91\x92\xb2\x17\x09\x0c\x2d\x99\x8d\x92\xb3\x29\x23\x36\xf2")); -snd($sock_b, $port_a, rtp(8, 4004, 8640, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4004, 8640, $ssrc, "\x3e\x20\x1b\x2d\xa0\x8d\x8c\xa1\x1c\x0a\x0c\x22\xa3\x94\x9a\xb5\x44\x5c\xb5\xb6\x32\x16\x0f\x1e\xa6\x8c\x8a\x99\x28\x0e\x0e\x20\xb7\xa1\xab\xd4\xdb\xaa\x9c\xa1\x38\x11\x0b\x15\xb5\x8d\x8a\x96\x3f\x16\x15\x26\xdd\xc2\x43\x31\xdf\x9d\x90\x96\x6d\x11\x09\x0f\x5a\x93\x8c\x97\xd2\x23\x23\x3b\xf6\x37\x1f\x1d\x40\x9a\x8c\x8e\xb2\x15\x09\x0e\x31\x9c\x93\x9c\xc2\x3e\x74\xb4\xbf\x29\x14\x11\x29\x9b\x8a\x8b\xa3\x1c\x0d\x0f\x2a\xab\x9f\xad\xe0\xcc\xa6\x9c\xa9\x28\x0e\x0c\x1c\xa2\x8b\x8b\x9c\x2a\x14\x17\x2c\xc6\xc4\x3e\x36\xbd\x99\x90\x9b\x30\x0d\x09\x15\xb3\x8f\x8d\x9b\x42\x1f\x25\x42\x70\x30\x1e\x1f\xcf\x95\x8b\x92\x58\x0f\x09\x12\x6f\x98\x93")); -snd($sock_b, $port_a, rtp(8, 4005, 8800, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4005, 8800, $ssrc, "\x9f\xe5\x3b\xe2\xb5\xd9\x21\x12\x14\x3e\x95\x89\x8d\xb6\x16\x0c\x13\x3a\xa4\x9f\xb1\xf1\xc0\xa3\x9d\xb4\x1e\x0d\x0d\x27\x99\x8a\x8c\xa7\x1f\x12\x19\x37\xbc\xc8\x3c\x3c\xaf\x97\x91\xa2\x21\x0b\x0a\x1c\xa2\x8d\x8e\xa2\x2f\x1e\x28\x4c\x5d\x2c\x1e\x25\xb0\x90\x8c\x98\x2c\x0c\x0a\x18\xb4\x94\x94\xa6\x4d\x3a\xd4\xb8\x4f\x1d\x11\x18\xc5\x8f\x89\x91\x4d\x10\x0c\x17\xec\x9f\xa0\xb8\xff\xba\xa1\x9f\xd3\x19\x0c\x0f\x3f\x92\x89\x8f\xbb\x19\x11\x1c\x48\xb8\xce\x3b\x4a\xa8\x95\x93\xaf\x19\x0a\x0c\x29\x99\x8c\x8f\xad\x27\x1d\x2b\x59\x4f\x29\x1e\x2d\xa5\x8e\x8d\x9f\x1e\x0b\x0b\x1e\xa4\x91\x96\xad\x3e\x3b\xcc\xbc\x3a\x1a\x12\x1e\xaa\x8d\x8a\x98\x2b")); -snd($sock_b, $port_a, rtp(8, 4006, 8960, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4006, 8960, $ssrc, "\x0e\x0c\x1d\xb8\x9d\xa2\xbe\xf9\xb4\xa0\xa3\x3f\x14\x0c\x14\xbd\x8e\x89\x93\x49\x15\x12\x1f\xe7\xb5\xd9\x3c\x7c\xa1\x93\x97\xd5\x13\x09\x0e\x45\x93\x8b\x93\xc4\x20\x1d\x2e\x6b\x46\x26\x1f\x3d\x9d\x8d\x8e\xae\x17\x09\x0d\x2c\x9c\x90\x98\xba\x36\x3d\xc7\xc4\x2e\x17\x13\x27\x9e\x8b\x8b\x9f\x1e\x0c\x0e\x25\xaa\x9c\xa5\xc8\xe8\xae\xa0\xaa\x2d\x10\x0c\x1b\xa6\x8c\x8a\x9a\x2c\x12\x13\x27\xc3\xb3\xed\x3e\xc8\x9d\x93\x9b\x38\x0f\x09\x13\xba\x8f\x8b\x98\x4a\x1d\x1e\x34\xf9\x3e\x24\x23\xea\x98\x8c\x92\xdf\x10\x09\x0f\x4d\x97\x90\x9c\xd2\x31\x3f\xc5\xd6\x28\x16\x16\x39\x97\x8a\x8d\xaf\x17\x0b\x10\x32\xa2\x9b\xa8\xd6\xd9\xac\xa1\xb3\x22\x0e\x0e")); -snd($sock_b, $port_a, rtp(8, 4007, 9120, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4007, 9120, $ssrc, "\x24\x9b\x8a\x8b\xa2\x1f\x10\x15\x2f\xb8\xb4\x68\x43\xb8\x9a\x94\xa1\x25\x0c\x0a\x1a\xa5\x8d\x8c\x9e\x30\x1b\x1f\x3c\xee\x38\x23\x28\xb8\x93\x8d\x97\x31\x0d\x09\x15\xb9\x93\x90\xa0\x4f\x2f\x46\xc4\x5e\x21\x15\x19\xd7\x91\x89\x90\x7b\x10\x0b\x14\x5b\x9d\x9c\xad\xed\xcd\xa9\xa3\xca\x1c\x0d\x10\x38\x94\x89\x8e\xb3\x19\x0f\x18\x3e\xb0\xb5\x59\x4d\xae\x98\x95\xad\x1c\x0b\x0c\x25\x9b\x8b\x8e\xa9\x26\x1a\x22\x46\xf5\x33\x23\x2e\xaa\x90\x8d\x9e\x21\x0b\x0a\x1c\xa6\x90\x92\xa8\x3b\x2e\x4d\xc7\x43\x1e\x15\x1e\xaf\x8e\x8a\x96\x2e\x0e\x0b\x1a\xbb\x9b\x9d\xb2\x68\xc5\xa8\xa7\x4c\x17\x0d\x14\xcb\x8f\x89\x91\x5e\x14\x0f\x1c\x6e\xad\xb8\x52\x68\xa8")); -snd($sock_b, $port_a, rtp(8, 4008, 9280, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4008, 9280, $ssrc, "\x97\x98\xc7\x16\x0a\x0e\x3a\x94\x8a\x90\xbb\x1e\x1a\x27\x56\x6f\x2f\x25\x3b\xa0\x8e\x8f\xaa\x19\x09\x0c\x28\x9c\x8f\x95\xb2\x31\x2e\x59\xcc\x37\x1b\x16\x26\xa1\x8c\x8b\x9d\x1f\x0c\x0c\x20\xab\x99\x9e\xbb\x5d\xbe\xa7\xac\x32\x13\x0d\x1a\xab\x8c\x89\x97\x2e\x10\x10\x21\xc3\xab\xbc\x4f\xd4\xa2\x96\x9c\x3f\x10\x0a\x12\xc4\x8f\x8a\x95\x57\x1b\x1a\x2b\xfd\x5d\x2d\x27\x62\x9b\x8e\x92\xc9\x12\x09\x0e\x3f\x97\x8e\x98\xc6\x2c\x2f\x6b\xd9\x2e\x1a\x18\x34\x9a\x8b\x8d\xab\x18\x0a\x0e\x2d\xa1\x98\xa1\xc7\x5b\xb9\xa7\xb4\x27\x10\x0e\x22\x9d\x8a\x8b\x9f\x20\x0e\x12\x2a\xb4\xaa\xc0\x50\xc0\x9e\x97\xa1\x2a\x0e\x0a\x19\xa8\x8c\x8b\x9b\x31\x18\x1b\x31")); -snd($sock_b, $port_a, rtp(8, 4009, 9440, 0x6543, "\x2a" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4009, 9440, $ssrc, "\xda\x50\x2c\x2b\xc0\x97\x8e\x97\x39\x0e\x09\x13\xbf\x92\x8e\x9c\x57\x29\x31\xef\x72\x28\x19\x1b\x6d\x94\x8a\x8f\xce\x11\x0a\x11\x48\x9c\x98\xa5\xdc\x5e\xb5\xa9\xc6\x1f\x0f\x10\x31\x96\x89\x8d\xad\x19\x0e\x15\x37\xac\xaa\xc8\x57\xb7\x9c\x98\xac\x1e\x0c\x0c\x21\x9c\x8b\x8d\xa4\x25\x17\x1d\x3b\xcf\x48\x2b\x30\xae\x93\x8e" . "\xff" x 80)); -# pause -snd($sock_b, $port_a, rtp(0, 4010, 9600, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4010, 9600, $ssrc, "\xff" x 160)); -snd($sock_b, $port_a, rtp(0, 4011, 9760, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4011, 9760, $ssrc, "\xff" x 160)); -snd($sock_b, $port_a, rtp(0, 4012, 9920, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4012, 9920, $ssrc, "\xff" x 160)); -snd($sock_b, $port_a, rtp(0, 4013, 10080, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4013, 10080, $ssrc, "\xff" x 160)); -snd($sock_b, $port_a, rtp(0, 4014, 10240, 0x6543, "\x00" x 160)); -rcv($sock_a, $port_b, rtpm(0, 4014, 10240, $ssrc, "\xff" x 80 . "\x00" x 80)); +snd($sock_a, $port_b, rtp(96, 1000, 3000, 0x6543, "\xa2\xff\x30\x0e\x5b\x3e\xa0\xac\x40\x40\x00\x57\xff\xff\xfd\xa4\x58\x8b\x62\x10\xcf\xff\xb9\xaa\xbb\xff\xcc\xc0\x00\x00\x00\x00\x00\x0c\x31\x1c\xc1\x74\xaf\x85\x85\x9a\x32\x33\x63\x60\x21\x61\x58\x76")); +($ssrc) = rcv($sock_b, $port_a, rtpm(8, 1000, 3000, -1, "\xd5\x55\x57\x5e\x65\x03\x2a\x2a\x2a\xaa\xaa\xaa\xaa\x2a\xaa\x2a\xaa\x2a\x2a\xaa\xaa\xaa\xaa\xaa\xaa\x2a\xaa\xaa\xaa\xaa\xab\x2a\xaa\xa8\x2a\xaa\x2a\xaa\x2a\x2a\x2a\x2a\x2a\x2b\x2a\x2e\x2e\x2a\x2a\x2e\x26\xaa\xaa\xaa\x3c\x2a\x2a\xad\xad\xa3\xa7\xa7\xa3\xa2\xa1\xa3\xa4\xba\xbe\xb2\xb6\x8a\x86\x9f\x96\xee\x9b\x81\x84\x9d\x99\x9a\x85\x87\x84\x8f\x8d\x82\x83\xed\x97\x95\x87\x8b\xb1\x81\x81\x9b\x9c\xea\xcc\x79\x6c\x11\x13\x1b\x18\x19\x19\x1f\x12\x10\x12\x1d\x10\x16\x14\x6b\x68\x66\x64\x7a\x7e\x7d\x72\x72\x7c\x7f\x79\x65\x65\x60\x61\x61\x61\x7f\x7c\x72\x78\x67\x62\x78\x7a\x78\x7f\x71\x48\x44\x5c\x55\xd3\xd9\xc4\xc6\xc1\xc1\xc6\xc4\xda\xd8\xd8\xd9\xdc\xda\xdd\xdf\xd3\xd2\xd6\xda\xdd\xdf\xde\xd8\xdb\xda\xdb\xda\xdb\xda\xd8\xd9\xde\xdf\xdc\xdd\xdd\xd2\xd3\xd3\xd3\xd0\xd0\xd1\xd1\xd0\xd1\xd1\xd1\xd1\xd1\xd1\xd1\xd6\xd6\xd6\xd7\xd7\xd7\xd4\xd4\xd4\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\xd5\x55\xd5\x55\x55\x55\x55\x55\x55\x55\x55\x54\x54\x54\x54\x54\x54\x54\x54")); +# mode switch +snd($sock_a, $port_b, rtp(96, 1001, 3240, 0x6543, "\xa2\xff\x37\xd3\xe2\xb8\x50\x40\x00\x5f\xff\xff\xff\x89\xcc\xff\x76\x6a\xae\xff\xcc\x00\x00\x00\x00\x00\x00\x00\x36\x52\x9d\x93\xf8\x45\x45\x45\x12\x16")); +($ssrc) = rcv($sock_b, $port_a, rtpm(8, 1001, 3240, -1, "\xd5\xd5\x55\xaa\x2a\xaa\xaa\x2a\xaa\xaa\xaa\x2a\x2a\xaa\x2a\x2a\x2a\x2a\xaa\xaa\x2a\xaa\x2a\xaa\x2a\xaa\x2a\x2a\xa7\x2a\x2a\x2a\xaa\xaa\x2a\xaa\xaa\x2a\x2a\x2a\x2a\xaa\xaa\xaa\xaa\x2a\x2a\xaa\xaa\xaa\x2a\x2a\x2a\x2a\xaa\x2a\xaa\x2a\xaa\xaa\x2a\x2a\x2a\x2a\x2a\x2a\xaa\x2a\x2a\x2a\x2a\x28\xaa\x2a\x28\xaa\x3e\xaa\xaa\x2a\x2a\xaa\x2a\x2a\xaa\x2a\xaa\xaa\xaa\x81\x36\x2a\x2a\x2a\x2a\xaa\xaa\x2a\xaa\xaa\x2a\xaa\x2a\x2a\x2a\xa5\xaa\xaa\xaa\xaa\xaa\x2a\x2a\xaa\x2a\x2a\xaa\x2a\xaa\xaa\xaa\xaa\xa2\xa4\xaf\x7e\xec\x37\x26\x21\x2f\x28\x29\x2a\x28\x2e\x2f\x22\x20\x27\x25\x39\x32\x31\x34\x0b\x0e\x0c\x0d\x02\x03\x01\x01\x06\x06\x06\x07\x04\x05\x1e")); +snd($sock_b, $port_a, rtp(8, 1000, 3000, 0x1234, "\x00" x 240)); +($ssrc) = rcv($sock_a, $port_b, rtpm(96, 1000, 3000, -1, "\xa2\xff\x30\x0e\x5b\x3e\xa0\xac\x40\x40\x00\x57\xff\xff\xfd\xa4\x58\x8b\x62\x10\xcf\xff\xb9\xaa\xbb\xff\xcc\xc0\x00\x00\x00\x00\x00\x0c\x31\x1c\xc1\x74\xaf\x85\x85\x9a\x32\x33\x63\x60\x21\x61\x58\x76")); -# multiple consecutive DTMF events -($sock_a, $sock_b) = new_call([qw(198.51.100.1 6024)], [qw(198.51.100.3 6026)]); +($sock_a, $sock_b) = new_call([qw(198.51.100.1 7322)], [qw(198.51.100.3 7324)]); -($port_a) = offer('multiple consecutive DTMF events', - { ICE => 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'remove', replace => ['origin'], codec => { transcode => ['PCMA'] } }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < ft(), code => 'C', volume => 5, duration => 100 }); -$resp = rtpe_req('play DTMF', 'inject DTMF towards B', - { 'from-tag' => ft(), code => '4', volume => 5, duration => 100 }); - -snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1002, 3320, $ssrc, "\xff\x93\x94\xbc\x2e\x56\xbf\x2b\x13\x1b\xa7\x8e\x98\x47\x25\x41\xe2\x24\x16\x2b\x99\x8e\x9f\x28\x1e\x3d\x5b\x23\x1c\xdf\x92\x8f\xb6\x1c\x1c\x40\x5d\x26\x25\xaa\x8f\x95\x3b\x15\x1d\x5e\xde\x2c\x38\x9d\x8f\x9e\x1f\x11\x20\xc0\xc1\x37\xdd\x99\x92\xb7\x15\x10\x2c\xac\xb5\x49\xb8\x97\x99\x37\x0f\x13\x58\xa0\xae\x67\xae\x99\xa4\x1f\x0d\x1a\xae\x9b\xad\x7b\xad\x9d\xbf\x16\x0e\x27\x9d\x98\xb0\x55\xb1\xa6\x3a\x11\x11\x63\x95\x98\xbf\x3e\xbb\xb4\x26\x10\x1a\xa9\x90\x9a\x4e\x30\xce\xd4\x1e\x12\x29\x99\x8e\xa1\x2d\x29\x6d\x4b\x1c\x18\xef\x91\x8f\xb6\x1f\x24\x57\x3e\x1d\x20\xa9\x8e\x95\x3e\x19\x23\x67\x3e\x21\x31\x9c\x8e\x9e\x22\x14\x26\xcd\x4a")); -snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1003, 3480, $ssrc, "\x2a\xdf\x96\x90\xb5\x17\x13\x2f\xb6\xf5\x36\xb1\x93\x96\x39\x10\x15\x55\xaa\xc8\x4c\xa7\x95\xa0\x1f\x0e\x1b\xb4\xa1\xbd\xed\xa4\x99\xbb\x15\x0e\x27\xa0\x9d\xbd\xda\xa4\x9f\x39\x10\x11\x58\x98\x9c\xc8\xf9\xa9\xac\x23\x0e\x19\xab\x92\x9e\x59\x4c\xb0\xca\x1b\x10\x27\x9a\x90\xa5\x35\x3a\xbe\x43\x18\x15\x6c\x92\x91\xb7\x26\x30\xd6\x32\x18\x1d\xa9\x8e\x96\x44\x1d\x2d\xfc\x2e\x1b\x2d\x9a\x8d\x9e\x25\x19\x2d\xe7\x2f\x20\xea\x94\x8f\xb3\x19\x17\x36\xc8\x36\x2c\xae\x90\x95\x3b\x12\x18\x55\xb7\x43\x3e\xa1\x91\x9e\x1f\x0f\x1d\xba\xac\x64\xe8\x9d\x95\xb7\x15\x0e\x29\xa6\xa6\xda\xc3\x9d\x9b\x39\x0f\x11\x51\x9c\xa2\xd8\xbe\x9f\xa7\x21\x0e\x18\xad")); -snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1004, 3640, $ssrc, "\x96\xa3\x68\xc4\xa5\xc2\x19\x0e\x26\x9c\x93\xa9\x3f\xdb\xae\x3e\x14\x12\x5b\x93\x93\xb9\x2e\x51\xbe\x2c\x14\x1b\xa9\x8f\x97\x4c\x25\x3f\xde\x25\x16\x2a\x9a\x8e\x9e\x29\x1e\x3b\x5e\x24\x1b\x7b\x92\x8f\xb2\x1c\x1c\x3e\x61\x27\x25\xac\x8f\x94\x3e\x15\x1c\x59\xdb\x2d\x37\x9e\x8f\x9d\x20\x11\x1f\xc2\xbf\x38\xea\x99\x92\xb4\x16\x10\x2b\xad\xb4\x49\xba\x98\x98\x3a\x0f\x12\x4e\xa1\xad\x68\xaf\x99\xa3\x20\x0d\x19\xb0\x9b\xac\x7b\xae\x9d\xbc\x17\x0e\x25\x9e\x98\xaf\x55\xb2\xa6\x3d\x12\x11\x52\x96\x97\xbd\x3e\xbc\xb3\x28\x10\x19\xab\x90\x9a\x54\x2f\xd0\xcf\x1f\x12\x27\x9a\x8e\xa0\x2e\x28\x66\x4e\x1d\x18\x62\x92\x8f\xb2\x20\x23\x53\x3f\x1d\x1f")); -snd($sock_a, $port_b, rtp(0, 1005, 3800, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1005, 3800, $ssrc, "\xab\x8e\x94\x44\x19\x22\x61\x40\x21\x2f\x9c\x8e\x9d\x23\x14\x25\xce\x4d\x2a\xf7\x96\x8f\xb1\x18\x13\x2e\xb7\xe8\x36\xb3\x94\x96\x3c\x10\x15\x4d\xaa\xc5\x4b\xa8\x95\x9f\x20\x0e\x1a\xb6\xa0\xbc\xf5\xa4\x99\xb8\x16\x0e\x26\xa1\x9d\xbb\xdd\xa5\x9f\x3c\x10\x10\x4c\x99\x9b\xc5\x78\xaa\xac\x24\x0f\x18\xac\x93\x9d\x5f\x4a\xb1\xc7\x1c\x0f\x25\x9b\x90\xa3\x36\x39\xbf\x47\x18\x14\x56\x92\x90\xb4\x27\x2f\xd7\x34\x18\x1c\xab\x8e\x95\x4b\x1d\x2c\xfe\x2f\x1b\x2c\x9b\x8d\x9d\x27\x19\x2c\xe7\x30\x20\x6d\x94\x8f\xaf\x1a\x17\x34\xc8\x37\x2b\xaf\x91\x94\x3f\x12\x18\x4e\xb6\x45\x3d\xa3\x91\x9e\x20\x0f\x1c\xbc\xab\x6c\xf5\x9e\x95\xb3\x16\x0e\x27\xa7\xa5")); -snd($sock_a, $port_b, rtp(0, 1006, 3960, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1006, 3960, $ssrc, "\xd6\xc6\x9d\x9b\x3d\x0f\x11\x49\x9c\xa1\xd4\xbf\x9f\xa6\x22\x0e\x18\xaf\x96\xa2\x6e\xc6\xa5\xbe\x19\x0e\x24\x9d\x93\xa8\x40\xe1\xae\x42\x15\x12\x4e\x94\x93\xb7\x2e\x4e\xbe\x2d\x14\x1a\xab\x8f\x97\x52\x25\x3e\xdc\x26\x16\x28\x9b\x8e\x9e\x2b\x1e\x3a\x61\x25\x1b\x5d\x93\x8f\xaf\x1d\x1c\x3d\x67\x27\x24\xad\x8f\x93\x45\x15\x1c\x53\xd7\x2d\x35\x9f\x8f\x9c\x22\x11\x1f\xc5\xbe\x38\x7a\x9a\x91\xb0\x17\x10\x29\xad\xb3\x4a\xbc\x98\x98\x3e\x10\x12\x48\xa1\xad\x6a\xb1\x9a\xa1\x21\x0e\x18\xb3\x9b\xab\x7d\xaf\x9d\xb9\x18\x0e\x23\x9f\x97\xae\x55\xb4\xa5\x40\x12\x10\x49\x96\x97\xbb\x3d\xbd\xb2\x29\x10\x18\xac\x90\x99\x5d\x2f\xd4\xcd\x1f\x12\x25\x9b")); -# pause -snd($sock_a, $port_b, rtp(0, 1007, 4120, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1007, 4120, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1008, 4280, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1009, 4440, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1009, 4440, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1010, 4600, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1010, 4600, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1011, 4760, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1011, 4760, $ssrc, "\xff" x 160)); -# next event -snd($sock_a, $port_b, rtp(0, 1012, 4920, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1012, 4920, $ssrc, "\xff\x96\x8e\x99\xdd\x1f\x1d\x2c\x69\xe9\x39\x2d\x50\xa3\x95\x97\xbd\x1a\x0e\x12\x38\x9d\x93\x9b\xbf\x30\x2f\x4f\xdc\x39\x20\x1d\x33\xa2\x90\x91\xaa\x1f\x0f\x12\x2c\xa9\x9c\xa3\xc2\x55\xc9\xaf\xb8\x30\x18\x14\x24\xa7\x8f\x8e\xa0\x2a\x14\x16\x2a\xbc\xac\xbc\x61\xcf\xa8\x9d\xa6\x36\x15\x0f\x1b\xb4\x92\x8f\x9d\x3e\x1d\x1e\x31\xe0\xfe\x36\x30\xd3\x9e\x94\x9b\x50\x15\x0d\x17\xe3\x99\x93\x9e\xee\x2c\x30\x5b\xf0\x32\x1f\x1f\x4c\x9c\x8f\x94\xbe\x19\x0e\x15\x3d\xa2\x9b\xa7\xd2\x52\xc3\xaf\xc4\x29\x16\x16\x2f\x9e\x8e\x90\xac\x20\x13\x18\x34\xb2\xac\xc0\x61\xc2\xa5\x9d\xad\x29\x12\x10\x23\xa5\x8f\x90\xa5\x2d\x1b\x1f\x39\xd1\x65\x34\x36\xbb\x9b")); -snd($sock_a, $port_b, rtp(0, 1013, 5080, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1013, 5080, $ssrc, "\x94\x9f\x2f\x11\x0e\x1c\xb3\x95\x94\xa4\x45\x2a\x33\x69\x60\x2d\x1e\x23\xc7\x98\x8f\x98\x49\x15\x0e\x1a\xda\x9d\x9c\xab\x7d\x53\xbe\xb1\xe8\x22\x15\x19\x4d\x98\x8d\x94\xc3\x1b\x12\x1b\x48\xac\xac\xc7\x69\xba\xa2\x9f\xbb\x1f\x10\x12\x2f\x9c\x8e\x93\xb0\x25\x1a\x22\x44\xcb\x57\x34\x3d\xae\x99\x96\xa9\x23\x0f\x0f\x24\xa6\x93\x96\xac\x36\x29\x37\x7c\x4e\x29\x1e\x29\xb0\x94\x8f\x9e\x2d\x11\x0f\x1f\xb6\x9b\x9d\xb0\x55\x58\xbc\xb5\x49\x1e\x15\x1d\xbe\x94\x8e\x99\x45\x17\x12\x1f\xd9\xa9\xad\xce\xfa\xb3\xa0\xa2\xef\x1b\x0f\x16\x52\x97\x8e\x96\xcb\x1e\x1a\x26\x59\xc8\x4e\x35\x4d\xa8\x97\x98\xb8\x1c\x0e\x11\x31\x9d\x91\x98\xb9\x2d\x29\x3b\xf5")); -snd($sock_a, $port_b, rtp(0, 1014, 5240, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1014, 5240, $ssrc, "\x43\x27\x1f\x32\xa6\x92\x91\xa7\x21\x0f\x10\x28\xa9\x99\x9e\xba\x49\x60\xba\xbb\x38\x1b\x16\x23\xab\x90\x8e\x9e\x2d\x14\x13\x26\xbc\xa7\xaf\xd8\xde\xae\xa0\xa7\x3d\x17\x0f\x1a\xba\x93\x8e\x9b\x44\x1b\x1b\x2b\xe0\xc8\x48\x37\xe4\xa2\x96\x9b\x6f\x17\x0e\x15\x5d\x99\x91\x9c\xd7\x29\x29\x3f\xf8\x3c\x24\x21\x46\x9e\x90\x94\xb8\x1a\x0e\x14\x37\xa1\x99\xa1\xc8\x43\x76\xba\xc5\x2d\x19\x17\x2d\xa0\x8f\x8f\xa8\x21\x11\x16\x2e\xaf\xa6\xb2\xe5\xcf\xab\xa0\xad\x2d\x14\x10\x20\xa8\x90\x8f\xa1\x2e\x19\x1c\x31\xcb\xc9\x44\x3b\xc2\x9e\x96\x9f\x36\x13\x0e\x1a\xb8\x95\x92\xa0\x48\x26\x2a\x48\x73\x36\x23\x25\xd4\x9a\x90\x98\x5c\x15\x0e\x18\x72\x9c\x99")); -snd($sock_a, $port_b, rtp(0, 1015, 5400, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1015, 5400, $ssrc, "\xa6\xe8\x3f\xe7\xba\xdd\x27\x18\x1a\x43\x9a\x8e\x93\xbb\x1b\x10\x19\x3e\xaa\xa5\xb7\xf4\xc6\xa9\xa2\xba\x23\x12\x12\x2c\x9e\x8e\x91\xac\x25\x18\x1e\x3c\xc1\xcd\x41\x40\xb5\x9c\x97\xa8\x27\x10\x0f\x21\xa8\x92\x93\xa8\x35\x24\x2c\x50\x61\x30\x23\x2b\xb7\x97\x90\x9d\x31\x11\x0e\x1c\xb9\x9a\x9a\xab\x52\x3f\xd9\xbc\x54\x22\x18\x1d\xca\x96\x8e\x97\x52\x17\x10\x1c\xef\xa5\xa6\xbc\xff\xbe\xa7\xa5\xd8\x1d\x10\x16\x45\x98\x8e\x95\xbf\x1e\x17\x20\x4d\xbc\xd2\x3f\x4e\xad\x9a\x99\xb4\x1e\x0e\x10\x2d\x9e\x90\x96\xb2\x2c\x22\x2f\x5c\x54\x2d\x24\x32\xaa\x94\x91\xa5\x24\x0f\x0f\x24\xaa\x98\x9b\xb2\x43\x3f\xcf\xc0\x3e\x1e\x18\x23\xaf\x92\x8e\x9c\x2f")); -snd($sock_a, $port_b, rtp(0, 1016, 5560, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1016, 5560, $ssrc, "\x13\x11\x21\xbd\xa2\xa8\xc3\xfa\xb9\xa6\xa9\x45\x19\x10\x1a\xc2\x94\x8e\x99\x4e\x1a\x18\x26\xeb\xba\xdd\x40\x7d\xa7\x99\x9c\xda\x19\x0e\x14\x4a\x99\x90\x99\xc9\x26\x23\x34\x6d\x4b\x2b\x25\x41\xa1\x92\x94\xb3\x1c\x0e\x12\x30\xa0\x96\x9d\xbe\x3b\x41\xcc\xc9\x34\x1c\x19\x2c\xa3\x8f\x8f\xa5\x23\x10\x13\x2a\xaf\xa0\xaa\xcd\xeb\xb4\xa6\xae\x31\x16\x11\x1f\xab\x90\x8e\x9e\x30\x18\x19\x2c\xc8\xb9\xf0\x43\xcc\xa2\x99\x9f\x3c\x14\x0e\x19\xbe\x95\x90\x9d\x4e\x22\x24\x3a\xfa\x43\x2a\x28\xec\x9d\x91\x98\xe4\x16\x0d\x16\x51\x9c\x96\xa0\xd7\x37\x45\xca\xda\x2c\x1b\x1b\x3d\x9c\x8e\x92\xb4\x1c\x0f\x16\x38\xa8\xa0\xad\xda\xdd\xb0\xa7\xb9\x28\x14\x13")); -# pause -snd($sock_a, $port_b, rtp(0, 1017, 5720, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1017, 5720, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1018, 5880, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1018, 5880, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1019, 6040, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1019, 6040, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1020, 6200, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1020, 6200, $ssrc, "\xff" x 160)); -snd($sock_a, $port_b, rtp(0, 1021, 6360, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1021, 6360, $ssrc, "\xff" x 160)); -# resume -snd($sock_a, $port_b, rtp(0, 1022, 6520, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1022, 6520, $ssrc, "\x00" x 160)); +a=ptime:20 +SDP + +($port_b) = answer('gh854 inbound 20 ms', + { ICE => 'remove', replace => ['origin'] }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < ft(), code => '0', volume => 10, duration => 100 }); -$resp = rtpe_req('play DTMF', 'inject DTMF towards B', - { 'from-tag' => ft(), code => '1', volume => 6, duration => 100 }); snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); rcv($sock_b, $port_a, rtpm(96 | 0x80, 1002, 3320, $ssrc, "\x00\x0a\x00\xa0")); @@ -8249,297 +5972,306 @@ rcv($sock_b, $port_a, rtpm(96, 1008, 3320, $ssrc, "\x00\x8a\x03\xc0")); rcv($sock_b, $port_a, rtpm(96, 1009, 3320, $ssrc, "\x00\x8a\x03\xc0")); snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); rcv($sock_b, $port_a, rtpm(0, 1010, 4280, $ssrc, "\x00" x 160)); -snd($sock_a, $port_b, rtp(0, 1009, 4440, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1011, 4440, $ssrc, "\x00" x 160)); -snd($sock_a, $port_b, rtp(0, 1010, 4600, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1012, 4600, $ssrc, "\x00" x 160)); -snd($sock_a, $port_b, rtp(0, 1011, 4760, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1013, 4760, $ssrc, "\x00" x 160)); -snd($sock_a, $port_b, rtp(0, 1012, 4920, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96 | 0x80, 1014, 4920, $ssrc, "\x01\x06\x00\xa0")); -snd($sock_a, $port_b, rtp(0, 1013, 5080, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1015, 4920, $ssrc, "\x01\x06\x01\x40")); -snd($sock_a, $port_b, rtp(0, 1014, 5240, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1016, 4920, $ssrc, "\x01\x06\x01\xe0")); -snd($sock_a, $port_b, rtp(0, 1015, 5400, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1017, 4920, $ssrc, "\x01\x06\x02\x80")); -snd($sock_a, $port_b, rtp(0, 1016, 5560, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1018, 4920, $ssrc, "\x01\x06\x03\x20")); -snd($sock_a, $port_b, rtp(0, 1017, 5720, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(96, 1019, 4920, $ssrc, "\x01\x86\x03\xc0")); -rcv($sock_b, $port_a, rtpm(96, 1020, 4920, $ssrc, "\x01\x86\x03\xc0")); -rcv($sock_b, $port_a, rtpm(96, 1021, 4920, $ssrc, "\x01\x86\x03\xc0")); -snd($sock_a, $port_b, rtp(0, 1018, 5880, 0x1234, "\x00" x 160)); -rcv($sock_b, $port_a, rtpm(0, 1022, 5880, $ssrc, "\x00" x 160)); +snd($sock_b, $port_a, rtp(0, 4000, 8000, 0x6543, "\x00" x 160)); +($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 8000, -1, "\x00" x 160)); +snd($sock_b, $port_a, rtp(0, 4001, 8160, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4001, 8160, $ssrc, "\x00" x 160)); +$resp = rtpe_req('play DTMF', 'inject DTMF towards A', + { 'from-tag' => tt(), code => '*', volume => 10, duration => 100 }); -# SDP in/out tests, various ICE options +snd($sock_b, $port_a, rtp(0, 4002, 8320, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(96 | 0x80, 4002, 8320, $ssrc, "\x0a\x0a\x00\xa0")); +snd($sock_b, $port_a, rtp(0, 4003, 8480, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(96, 4003, 8320, $ssrc, "\x0a\x0a\x01\x40")); +snd($sock_b, $port_a, rtp(0, 4004, 8640, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(96, 4004, 8320, $ssrc, "\x0a\x0a\x01\xe0")); +snd($sock_b, $port_a, rtp(0, 4005, 8800, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(96, 4005, 8320, $ssrc, "\x0a\x0a\x02\x80")); +snd($sock_b, $port_a, rtp(0, 4006, 8960, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(96, 4006, 8320, $ssrc, "\x0a\x0a\x03\x20")); +snd($sock_b, $port_a, rtp(0, 4007, 9120, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(96, 4007, 8320, $ssrc, "\x0a\x8a\x03\xc0")); +rcv($sock_a, $port_b, rtpm(96, 4008, 8320, $ssrc, "\x0a\x8a\x03\xc0")); +rcv($sock_a, $port_b, rtpm(96, 4009, 8320, $ssrc, "\x0a\x8a\x03\xc0")); +snd($sock_b, $port_a, rtp(0, 4008, 9280, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4010, 9280, $ssrc, "\x00" x 160)); -new_call; -offer('plain SDP, no ICE', { ICE => 'remove' }, < 'remove' }, < 'default' }, < 'remove', replace => ['origin'], flags => ['inject DTMF'], + codec => { transcode => ['PCMA'] }}, < 'default' }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < ft(), code => '0', volume => 10, duration => 100 }); + +snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96 | 0x80, 1002, 3320, $ssrc, "\x00\x0a\x00\xa0")); +snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1003, 3320, $ssrc, "\x00\x0a\x01\x40")); +snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1004, 3320, $ssrc, "\x00\x0a\x01\xe0")); +snd($sock_a, $port_b, rtp(0, 1005, 3800, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1005, 3320, $ssrc, "\x00\x0a\x02\x80")); +snd($sock_a, $port_b, rtp(0, 1006, 3960, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1006, 3320, $ssrc, "\x00\x0a\x03\x20")); +snd($sock_a, $port_b, rtp(0, 1007, 4120, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1007, 3320, $ssrc, "\x00\x8a\x03\xc0")); +rcv($sock_b, $port_a, rtpm(96, 1008, 3320, $ssrc, "\x00\x8a\x03\xc0")); +rcv($sock_b, $port_a, rtpm(96, 1009, 3320, $ssrc, "\x00\x8a\x03\xc0")); +snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1010, 4280, $ssrc, "\x2a" x 160)); + + + +snd($sock_b, $port_a, rtp(8, 4000, 8000, 0x6543, "\x2a" x 160)); +($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 8000, -1, "\x00" x 160)); +snd($sock_b, $port_a, rtp(8, 4001, 8160, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4001, 8160, $ssrc, "\x00" x 160)); + +$resp = rtpe_req('play DTMF', 'inject DTMF towards A', + { 'from-tag' => tt(), code => '#', volume => -10, duration => 100 }); + +snd($sock_b, $port_a, rtp(8, 4002, 8320, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(96 | 0x80, 4002, 8320, $ssrc, "\x0b\x0a\x00\xa0")); +snd($sock_b, $port_a, rtp(8, 4003, 8480, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(96, 4003, 8320, $ssrc, "\x0b\x0a\x01\x40")); +snd($sock_b, $port_a, rtp(8, 4004, 8640, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(96, 4004, 8320, $ssrc, "\x0b\x0a\x01\xe0")); +snd($sock_b, $port_a, rtp(8, 4005, 8800, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(96, 4005, 8320, $ssrc, "\x0b\x0a\x02\x80")); +snd($sock_b, $port_a, rtp(8, 4006, 8960, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(96, 4006, 8320, $ssrc, "\x0b\x0a\x03\x20")); +snd($sock_b, $port_a, rtp(8, 4007, 9120, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(96, 4007, 8320, $ssrc, "\x0b\x8a\x03\xc0")); +rcv($sock_a, $port_b, rtpm(96, 4008, 8320, $ssrc, "\x0b\x8a\x03\xc0")); +rcv($sock_a, $port_b, rtpm(96, 4009, 8320, $ssrc, "\x0b\x8a\x03\xc0")); +snd($sock_b, $port_a, rtp(8, 4008, 9280, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4010, 9280, $ssrc, "\x00" x 160)); -offer('plain SDP, add default ICE', { ICE => 'optional' }, < 'remove' }, < 'remove' }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'optional' }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < '3.4.5.6', - flags => ['full-rtcp-attribute'], ICE => 'optional', }, < ft(), code => 'C', volume => 5, duration => 120, pause => 110 }); -new_call; +snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1002, 3320, $ssrc, "\xff\x93\x94\xbc\x2e\x56\xbf\x2b\x13\x1b\xa7\x8e\x98\x47\x25\x41\xe2\x24\x16\x2b\x99\x8e\x9f\x28\x1e\x3d\x5b\x23\x1c\xdf\x92\x8f\xb6\x1c\x1c\x40\x5d\x26\x25\xaa\x8f\x95\x3b\x15\x1d\x5e\xde\x2c\x38\x9d\x8f\x9e\x1f\x11\x20\xc0\xc1\x37\xdd\x99\x92\xb7\x15\x10\x2c\xac\xb5\x49\xb8\x97\x99\x37\x0f\x13\x58\xa0\xae\x67\xae\x99\xa4\x1f\x0d\x1a\xae\x9b\xad\x7b\xad\x9d\xbf\x16\x0e\x27\x9d\x98\xb0\x55\xb1\xa6\x3a\x11\x11\x63\x95\x98\xbf\x3e\xbb\xb4\x26\x10\x1a\xa9\x90\x9a\x4e\x30\xce\xd4\x1e\x12\x29\x99\x8e\xa1\x2d\x29\x6d\x4b\x1c\x18\xef\x91\x8f\xb6\x1f\x24\x57\x3e\x1d\x20\xa9\x8e\x95\x3e\x19\x23\x67\x3e\x21\x31\x9c\x8e\x9e\x22\x14\x26\xcd\x4a")); +snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1003, 3480, $ssrc, "\x2a\xdf\x96\x90\xb5\x17\x13\x2f\xb6\xf5\x36\xb1\x93\x96\x39\x10\x15\x55\xaa\xc8\x4c\xa7\x95\xa0\x1f\x0e\x1b\xb4\xa1\xbd\xed\xa4\x99\xbb\x15\x0e\x27\xa0\x9d\xbd\xda\xa4\x9f\x39\x10\x11\x58\x98\x9c\xc8\xf9\xa9\xac\x23\x0e\x19\xab\x92\x9e\x59\x4c\xb0\xca\x1b\x10\x27\x9a\x90\xa5\x35\x3a\xbe\x43\x18\x15\x6c\x92\x91\xb7\x26\x30\xd6\x32\x18\x1d\xa9\x8e\x96\x44\x1d\x2d\xfc\x2e\x1b\x2d\x9a\x8d\x9e\x25\x19\x2d\xe7\x2f\x20\xea\x94\x8f\xb3\x19\x17\x36\xc8\x36\x2c\xae\x90\x95\x3b\x12\x18\x55\xb7\x43\x3e\xa1\x91\x9e\x1f\x0f\x1d\xba\xac\x64\xe8\x9d\x95\xb7\x15\x0e\x29\xa6\xa6\xda\xc3\x9d\x9b\x39\x0f\x11\x51\x9c\xa2\xd8\xbe\x9f\xa7\x21\x0e\x18\xad")); +snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1004, 3640, $ssrc, "\x96\xa3\x68\xc4\xa5\xc2\x19\x0e\x26\x9c\x93\xa9\x3f\xdb\xae\x3e\x14\x12\x5b\x93\x93\xb9\x2e\x51\xbe\x2c\x14\x1b\xa9\x8f\x97\x4c\x25\x3f\xde\x25\x16\x2a\x9a\x8e\x9e\x29\x1e\x3b\x5e\x24\x1b\x7b\x92\x8f\xb2\x1c\x1c\x3e\x61\x27\x25\xac\x8f\x94\x3e\x15\x1c\x59\xdb\x2d\x37\x9e\x8f\x9d\x20\x11\x1f\xc2\xbf\x38\xea\x99\x92\xb4\x16\x10\x2b\xad\xb4\x49\xba\x98\x98\x3a\x0f\x12\x4e\xa1\xad\x68\xaf\x99\xa3\x20\x0d\x19\xb0\x9b\xac\x7b\xae\x9d\xbc\x17\x0e\x25\x9e\x98\xaf\x55\xb2\xa6\x3d\x12\x11\x52\x96\x97\xbd\x3e\xbc\xb3\x28\x10\x19\xab\x90\x9a\x54\x2f\xd0\xcf\x1f\x12\x27\x9a\x8e\xa0\x2e\x28\x66\x4e\x1d\x18\x62\x92\x8f\xb2\x20\x23\x53\x3f\x1d\x1f")); +snd($sock_a, $port_b, rtp(0, 1005, 3800, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1005, 3800, $ssrc, "\xab\x8e\x94\x44\x19\x22\x61\x40\x21\x2f\x9c\x8e\x9d\x23\x14\x25\xce\x4d\x2a\xf7\x96\x8f\xb1\x18\x13\x2e\xb7\xe8\x36\xb3\x94\x96\x3c\x10\x15\x4d\xaa\xc5\x4b\xa8\x95\x9f\x20\x0e\x1a\xb6\xa0\xbc\xf5\xa4\x99\xb8\x16\x0e\x26\xa1\x9d\xbb\xdd\xa5\x9f\x3c\x10\x10\x4c\x99\x9b\xc5\x78\xaa\xac\x24\x0f\x18\xac\x93\x9d\x5f\x4a\xb1\xc7\x1c\x0f\x25\x9b\x90\xa3\x36\x39\xbf\x47\x18\x14\x56\x92\x90\xb4\x27\x2f\xd7\x34\x18\x1c\xab\x8e\x95\x4b\x1d\x2c\xfe\x2f\x1b\x2c\x9b\x8d\x9d\x27\x19\x2c\xe7\x30\x20\x6d\x94\x8f\xaf\x1a\x17\x34\xc8\x37\x2b\xaf\x91\x94\x3f\x12\x18\x4e\xb6\x45\x3d\xa3\x91\x9e\x20\x0f\x1c\xbc\xab\x6c\xf5\x9e\x95\xb3\x16\x0e\x27\xa7\xa5")); +snd($sock_a, $port_b, rtp(0, 1006, 3960, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1006, 3960, $ssrc, "\xd6\xc6\x9d\x9b\x3d\x0f\x11\x49\x9c\xa1\xd4\xbf\x9f\xa6\x22\x0e\x18\xaf\x96\xa2\x6e\xc6\xa5\xbe\x19\x0e\x24\x9d\x93\xa8\x40\xe1\xae\x42\x15\x12\x4e\x94\x93\xb7\x2e\x4e\xbe\x2d\x14\x1a\xab\x8f\x97\x52\x25\x3e\xdc\x26\x16\x28\x9b\x8e\x9e\x2b\x1e\x3a\x61\x25\x1b\x5d\x93\x8f\xaf\x1d\x1c\x3d\x67\x27\x24\xad\x8f\x93\x45\x15\x1c\x53\xd7\x2d\x35\x9f\x8f\x9c\x22\x11\x1f\xc5\xbe\x38\x7a\x9a\x91\xb0\x17\x10\x29\xad\xb3\x4a\xbc\x98\x98\x3e\x10\x12\x48\xa1\xad\x6a\xb1\x9a\xa1\x21\x0e\x18\xb3\x9b\xab\x7d\xaf\x9d\xb9\x18\x0e\x23\x9f\x97\xae\x55\xb4\xa5\x40\x12\x10\x49\x96\x97\xbb\x3d\xbd\xb2\x29\x10\x18\xac\x90\x99\x5d\x2f\xd4\xcd\x1f\x12\x25\x9b")); +snd($sock_a, $port_b, rtp(0, 1007, 4120, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1007, 4120, $ssrc, "\x8e\x9f\x2f\x28\x5f\x51\x1d\x17\x52\x92\x8f\xaf\x20\x22\x50\x42\x1e\x1f\xad\x8e\x93\x4b\x19\x21\x5d\x42\x22\x2e\x9d\x8e\x9c\x25\x14\x24\xd0\x4f\x2a\x68\x97\x8f\xae\x18\x12\x2c\xb7\xdf\x36\xb6\x94\x95\x41\x11\x14\x48\xaa\xc3\x4a\xaa\x95\x9e\x21\x0e\x19\xb8\xa0\xba\xfe\xa5\x99\xb4\x17\x0e\x24\xa2\x9c\xba\xe0\xa6\x9e\x40\x10\x10\x45\x99\x9b\xc2\x6d\xaa\xab\x26\x0f\x17\xae\x93\x9c\x6a\x48\xb2\xc3\x1c\x0f\x23\x9c\x90\xa2\x37\x38\xbf\x4b\x19\x14\x4b\x93\x90\xb1\x27\x2e\xd8\x36\x19\x1c\xad\x8e\x94\x52\x1d\x2b\x7d\x30\x1b\x2a\x9c\x8d\x9c\x28\x19\x2b\xe7\x31\x20\x5a\x95\x8f\xad\x1a\x16\x32\xc8\x39\x2b\xb2\x91\x94\x46\x13\x17\x4a\xb6\x48\x3c")); +# pause +snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1008, 4280, $ssrc, "\xff" x 160)); +snd($sock_a, $port_b, rtp(0, 1009, 4440, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1009, 4440, $ssrc, "\xff" x 160)); +snd($sock_a, $port_b, rtp(0, 1010, 4600, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1010, 4600, $ssrc, "\xff" x 160)); +snd($sock_a, $port_b, rtp(0, 1011, 4760, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1011, 4760, $ssrc, "\xff" x 160)); +snd($sock_a, $port_b, rtp(0, 1012, 4920, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1012, 4920, $ssrc, "\xff" x 160)); +snd($sock_a, $port_b, rtp(0, 1013, 5080, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1013, 5080, $ssrc, "\xff" x 80 . "\x00" x 80)); -offer('ICE SDP, default ICE option', { ICE => 'optional' }, < tt(), code => '4', volume => 3, duration => 150, pause => 100 }); + +snd($sock_b, $port_a, rtp(0, 4002, 8320, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4002, 8320, $ssrc, "\xff\x90\x8a\x93\xd9\x1b\x18\x27\x65\xe5\x33\x29\x4c\x9e\x8f\x91\xb8\x15\x09\x0d\x32\x98\x8e\x96\xbb\x2c\x2b\x4c\xd8\x34\x1c\x18\x2e\x9d\x8c\x8c\xa5\x1a\x0b\x0d\x27\xa3\x97\x9e\xbd\x4f\xc4\xaa\xb2\x2c\x12\x0e\x1e\xa1\x8b\x8a\x9c\x25\x0e\x10\x25\xb7\xa7\xb7\x5e\xcb\xa2\x98\x9f\x30\x0f\x0a\x16\xae\x8d\x8a\x98\x3a\x18\x19\x2c\xdd\xfd\x30\x2b\xce\x99\x8e\x95\x4c\x0f\x09\x10\xdf\x93\x8e\x9a\xec\x28\x2c\x56\xee\x2d\x1a\x1a\x48\x97\x8b\x8e\xba\x14\x0a\x0f\x39\x9d\x96\xa1\xcd\x4e\xbe\xab\xbe\x23\x10\x10\x2b\x99\x8a\x8c\xa7\x1b\x0d\x12\x2f\xad\xa7\xbc\x5e\xbd\x9f\x99\xa8\x23\x0d\x0b\x1d\x9f\x8b\x8c\x9f\x29\x16\x1b\x34\xcd\x60\x2f\x2f\xb6\x96")); +snd($sock_b, $port_a, rtp(0, 4003, 8480, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4003, 8480, $ssrc, "\x8e\x9b\x2b\x0c\x09\x17\xae\x8f\x8e\x9e\x3f\x25\x2e\x65\x5c\x28\x1a\x1e\xc2\x92\x8a\x92\x44\x0f\x0a\x14\xd6\x99\x97\xa6\x7c\x4e\xba\xad\xe5\x1d\x0f\x13\x49\x92\x89\x8e\xbe\x15\x0d\x16\x43\xa8\xa7\xc1\x66\xb5\x9d\x9a\xb6\x1b\x0c\x0d\x2b\x98\x8a\x8d\xab\x1f\x15\x1d\x3f\xc7\x52\x2e\x39\xaa\x93\x8f\xa3\x1e\x0b\x0b\x1e\x9f\x8d\x8f\xa7\x30\x23\x31\x7c\x4a\x24\x1a\x24\xac\x8e\x8b\x99\x28\x0c\x0a\x1a\xb0\x96\x98\xac\x4f\x53\xb7\xaf\x44\x19\x0f\x18\xba\x8e\x89\x93\x3f\x10\x0d\x1a\xd5\xa3\xa8\xca\xf9\xae\x9c\x9d\xec\x16\x0b\x10\x4e\x91\x89\x90\xc6\x1a\x14\x20\x55\xc3\x4a\x2f\x49\xa2\x91\x92\xb2\x17\x09\x0c\x2d\x99\x8d\x92\xb3\x29\x23\x36\xf2")); +snd($sock_b, $port_a, rtp(0, 4004, 8640, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4004, 8640, $ssrc, "\x3e\x20\x1b\x2d\xa0\x8d\x8c\xa1\x1c\x0a\x0c\x22\xa3\x94\x9a\xb5\x44\x5c\xb5\xb6\x32\x16\x0f\x1e\xa6\x8c\x8a\x99\x28\x0e\x0e\x20\xb7\xa1\xab\xd4\xdb\xaa\x9c\xa1\x38\x11\x0b\x15\xb5\x8d\x8a\x96\x3f\x16\x15\x26\xdd\xc2\x43\x31\xdf\x9d\x90\x96\x6d\x11\x09\x0f\x5a\x93\x8c\x97\xd2\x23\x23\x3b\xf6\x37\x1f\x1d\x40\x9a\x8c\x8e\xb2\x15\x09\x0e\x31\x9c\x93\x9c\xc2\x3e\x74\xb4\xbf\x29\x14\x11\x29\x9b\x8a\x8b\xa3\x1c\x0d\x0f\x2a\xab\x9f\xad\xe0\xcc\xa6\x9c\xa9\x28\x0e\x0c\x1c\xa2\x8b\x8b\x9c\x2a\x14\x17\x2c\xc6\xc4\x3e\x36\xbd\x99\x90\x9b\x30\x0d\x09\x15\xb3\x8f\x8d\x9b\x42\x1f\x25\x42\x70\x30\x1e\x1f\xcf\x95\x8b\x92\x58\x0f\x09\x12\x6f\x98\x93")); +snd($sock_b, $port_a, rtp(0, 4005, 8800, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4005, 8800, $ssrc, "\x9f\xe5\x3b\xe2\xb5\xd9\x21\x12\x14\x3e\x95\x89\x8d\xb6\x16\x0c\x13\x3a\xa4\x9f\xb1\xf1\xc0\xa3\x9d\xb4\x1e\x0d\x0d\x27\x99\x8a\x8c\xa7\x1f\x12\x19\x37\xbc\xc8\x3c\x3c\xaf\x97\x91\xa2\x21\x0b\x0a\x1c\xa2\x8d\x8e\xa2\x2f\x1e\x28\x4c\x5d\x2c\x1e\x25\xb0\x90\x8c\x98\x2c\x0c\x0a\x18\xb4\x94\x94\xa6\x4d\x3a\xd4\xb8\x4f\x1d\x11\x18\xc5\x8f\x89\x91\x4d\x10\x0c\x17\xec\x9f\xa0\xb8\xff\xba\xa1\x9f\xd3\x19\x0c\x0f\x3f\x92\x89\x8f\xbb\x19\x11\x1c\x48\xb8\xce\x3b\x4a\xa8\x95\x93\xaf\x19\x0a\x0c\x29\x99\x8c\x8f\xad\x27\x1d\x2b\x59\x4f\x29\x1e\x2d\xa5\x8e\x8d\x9f\x1e\x0b\x0b\x1e\xa4\x91\x96\xad\x3e\x3b\xcc\xbc\x3a\x1a\x12\x1e\xaa\x8d\x8a\x98\x2b")); +snd($sock_b, $port_a, rtp(0, 4006, 8960, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4006, 8960, $ssrc, "\x0e\x0c\x1d\xb8\x9d\xa2\xbe\xf9\xb4\xa0\xa3\x3f\x14\x0c\x14\xbd\x8e\x89\x93\x49\x15\x12\x1f\xe7\xb5\xd9\x3c\x7c\xa1\x93\x97\xd5\x13\x09\x0e\x45\x93\x8b\x93\xc4\x20\x1d\x2e\x6b\x46\x26\x1f\x3d\x9d\x8d\x8e\xae\x17\x09\x0d\x2c\x9c\x90\x98\xba\x36\x3d\xc7\xc4\x2e\x17\x13\x27\x9e\x8b\x8b\x9f\x1e\x0c\x0e\x25\xaa\x9c\xa5\xc8\xe8\xae\xa0\xaa\x2d\x10\x0c\x1b\xa6\x8c\x8a\x9a\x2c\x12\x13\x27\xc3\xb3\xed\x3e\xc8\x9d\x93\x9b\x38\x0f\x09\x13\xba\x8f\x8b\x98\x4a\x1d\x1e\x34\xf9\x3e\x24\x23\xea\x98\x8c\x92\xdf\x10\x09\x0f\x4d\x97\x90\x9c\xd2\x31\x3f\xc5\xd6\x28\x16\x16\x39\x97\x8a\x8d\xaf\x17\x0b\x10\x32\xa2\x9b\xa8\xd6\xd9\xac\xa1\xb3\x22\x0e\x0e")); +snd($sock_b, $port_a, rtp(0, 4007, 9120, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4007, 9120, $ssrc, "\x24\x9b\x8a\x8b\xa2\x1f\x10\x15\x2f\xb8\xb4\x68\x43\xb8\x9a\x94\xa1\x25\x0c\x0a\x1a\xa5\x8d\x8c\x9e\x30\x1b\x1f\x3c\xee\x38\x23\x28\xb8\x93\x8d\x97\x31\x0d\x09\x15\xb9\x93\x90\xa0\x4f\x2f\x46\xc4\x5e\x21\x15\x19\xd7\x91\x89\x90\x7b\x10\x0b\x14\x5b\x9d\x9c\xad\xed\xcd\xa9\xa3\xca\x1c\x0d\x10\x38\x94\x89\x8e\xb3\x19\x0f\x18\x3e\xb0\xb5\x59\x4d\xae\x98\x95\xad\x1c\x0b\x0c\x25\x9b\x8b\x8e\xa9\x26\x1a\x22\x46\xf5\x33\x23\x2e\xaa\x90\x8d\x9e\x21\x0b\x0a\x1c\xa6\x90\x92\xa8\x3b\x2e\x4d\xc7\x43\x1e\x15\x1e\xaf\x8e\x8a\x96\x2e\x0e\x0b\x1a\xbb\x9b\x9d\xb2\x68\xc5\xa8\xa7\x4c\x17\x0d\x14\xcb\x8f\x89\x91\x5e\x14\x0f\x1c\x6e\xad\xb8\x52\x68\xa8")); +snd($sock_b, $port_a, rtp(0, 4008, 9280, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4008, 9280, $ssrc, "\x97\x98\xc7\x16\x0a\x0e\x3a\x94\x8a\x90\xbb\x1e\x1a\x27\x56\x6f\x2f\x25\x3b\xa0\x8e\x8f\xaa\x19\x09\x0c\x28\x9c\x8f\x95\xb2\x31\x2e\x59\xcc\x37\x1b\x16\x26\xa1\x8c\x8b\x9d\x1f\x0c\x0c\x20\xab\x99\x9e\xbb\x5d\xbe\xa7\xac\x32\x13\x0d\x1a\xab\x8c\x89\x97\x2e\x10\x10\x21\xc3\xab\xbc\x4f\xd4\xa2\x96\x9c\x3f\x10\x0a\x12\xc4\x8f\x8a\x95\x57\x1b\x1a\x2b\xfd\x5d\x2d\x27\x62\x9b\x8e\x92\xc9\x12\x09\x0e\x3f\x97\x8e\x98\xc6\x2c\x2f\x6b\xd9\x2e\x1a\x18\x34\x9a\x8b\x8d\xab\x18\x0a\x0e\x2d\xa1\x98\xa1\xc7\x5b\xb9\xa7\xb4\x27\x10\x0e\x22\x9d\x8a\x8b\x9f\x20\x0e\x12\x2a\xb4\xaa\xc0\x50\xc0\x9e\x97\xa1\x2a\x0e\x0a\x19\xa8\x8c\x8b\x9b\x31\x18\x1b\x31")); +snd($sock_b, $port_a, rtp(0, 4009, 9440, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4009, 9440, $ssrc, "\xda\x50\x2c\x2b\xc0\x97\x8e\x97\x39\x0e\x09\x13\xbf\x92\x8e\x9c\x57\x29\x31\xef\x72\x28\x19\x1b\x6d\x94\x8a\x8f\xce\x11\x0a\x11\x48\x9c\x98\xa5\xdc\x5e\xb5\xa9\xc6\x1f\x0f\x10\x31\x96\x89\x8d\xad\x19\x0e\x15\x37\xac\xaa\xc8\x57\xb7\x9c\x98\xac\x1e\x0c\x0c\x21\x9c\x8b\x8d\xa4\x25\x17\x1d\x3b\xcf\x48\x2b\x30\xae\x93\x8e" . "\xff" x 80)); +# pause +snd($sock_b, $port_a, rtp(0, 4010, 9600, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4010, 9600, $ssrc, "\xff" x 160)); +snd($sock_b, $port_a, rtp(0, 4011, 9760, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4011, 9760, $ssrc, "\xff" x 160)); +snd($sock_b, $port_a, rtp(0, 4012, 9920, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4012, 9920, $ssrc, "\xff" x 160)); +snd($sock_b, $port_a, rtp(0, 4013, 10080, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4013, 10080, $ssrc, "\xff" x 160)); +snd($sock_b, $port_a, rtp(0, 4014, 10240, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4014, 10240, $ssrc, "\xff" x 80 . "\x00" x 80)); + + + + +# transcoding, no RFC payload type present + +($sock_a, $sock_b) = new_call([qw(198.51.100.1 6018)], [qw(198.51.100.3 6020)]); + +($port_a) = offer('transcoding, no RFC payload type present', + { ICE => 'remove', replace => ['origin'], flags => ['inject DTMF'], + codec => { transcode => ['PCMA'] } }, < 'optional' }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < ft(), code => 'C', volume => 5, duration => 120 }); + +snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1002, 3320, $ssrc, "\xd5\xb9\xbe\x97\x05\x70\xea\x01\x3e\x31\x82\xa5\xb2\x63\x0f\x69\xc1\x0f\x3d\x06\xb3\xa4\x8a\x03\x35\x14\x75\x0e\x36\xcc\xb8\xa5\x9d\x36\x36\x68\x49\x0d\x0c\x81\xa5\xbf\x16\x3f\x37\x4f\xcf\x07\x13\xb4\xa5\xb4\x0a\x3b\x0b\xeb\xe9\x12\xc9\xb3\xb8\x92\x3c\x3a\x07\x87\x9c\x61\x93\xb2\xb3\x12\x25\x39\x76\x8b\x85\x5a\x85\xb3\x8e\x35\x24\x30\x85\xb1\x87\x57\x84\xb7\xeb\x3c\x24\x0d\xb4\xb2\x9b\x70\x98\x8c\x11\x3b\x38\x41\xbf\xb2\xeb\x15\x96\x9f\x0d\x3a\x30\x83\xba\xb1\x7b\x1b\xfa\xf2\x34\x39\x03\xb0\xa5\x88\x04\x03\x5f\x67\x37\x32\xdd\xb8\xba\x9d\x35\x0e\x71\x15\x37\x0a\x80\xa4\xbf\x15\x33\x09\x45\x15\x0b\x18\xb6\xa4\xb4\x08\x3f\x0d\xe5\x66")); +snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1003, 3480, $ssrc, "\x00\xcd\xbc\xba\x9c\x3d\x39\x1a\x9d\xd1\x1d\x98\xbe\xbd\x10\x3a\x3f\x73\x80\xe0\x64\x82\xbf\x8b\x35\x24\x31\x9f\x8b\x94\xdf\x8e\xb3\x96\x3c\x24\x02\x8b\xb7\x94\xf4\x8f\xb5\x10\x3a\x3b\x76\xb2\xb6\xe0\xd6\x80\x87\x09\x25\x33\x81\xb9\xb4\x74\x64\x9b\xe6\x31\x3a\x0d\xb1\xba\x8f\x1c\x11\x95\x6f\x32\x3f\x5e\xb8\xbb\x92\x0d\x1a\xf0\x19\x32\x37\x83\xa4\xbc\x6d\x37\x07\xd4\x04\x31\x07\xb1\xa4\xb4\x0c\x33\x04\xc5\x05\x0b\xd8\xbe\xa5\x9e\x30\x3d\x1d\xe0\x1d\x06\x84\xbb\xbf\x16\x38\x33\x73\x92\x6f\x15\x88\xbb\xb5\x35\x25\x37\x91\x86\x46\xda\xb7\xbf\x92\x3c\x25\x03\x8d\x8c\xf4\xef\xb7\xb6\x10\x25\x3b\x7f\xb6\x89\xf6\x95\xb5\x82\x0b\x24\x33\x84")); +snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1004, 3640, $ssrc, "\xbd\x8e\x5a\xec\x8c\xee\x33\x24\x0c\xb6\xbe\x80\x6b\xf5\x85\x6a\x3f\x39\x4a\xbe\xbe\x90\x05\x7f\x95\x06\x3e\x31\x80\xa5\xbd\x64\x0f\x6b\xcc\x0c\x3d\x00\xb0\xa4\xb5\x00\x34\x16\x4e\x0e\x36\x57\xb9\xa5\x99\x36\x36\x6a\x43\x0d\x0f\x86\xa5\xbe\x15\x3f\x36\x77\xf5\x07\x12\xb4\xa5\xb4\x0b\x3b\x0a\xee\xeb\x13\xd8\xb0\xb8\x9f\x3c\x3a\x01\x87\x9f\x66\x91\xb2\xb3\x11\x25\x39\x7a\x8b\x84\x5b\x9a\xb0\x89\x0a\x24\x33\x9b\xb1\x87\x54\x85\xb7\x97\x3d\x24\x0c\xb4\xb2\x9a\x73\x99\x8c\x14\x38\x3b\x7c\xbc\xbd\x94\x15\x97\x9e\x02\x3a\x33\x81\xba\xb0\x73\x1a\xfe\xf9\x35\x39\x02\xb1\xa4\x8a\x05\x03\x44\x7a\x37\x32\x40\xb8\xa5\x99\x0a\x0e\x72\x6b\x34\x35")); +snd($sock_a, $port_b, rtp(0, 1005, 3800, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1005, 3800, $ssrc, "\x81\xa4\xbe\x6c\x33\x08\x43\x68\x08\x1a\xb7\xa4\xb7\x0e\x3f\x0c\xfb\x65\x00\xd1\xbd\xba\x98\x32\x39\x04\x92\xdb\x1d\x9e\xbe\xbc\x17\x3a\x3f\x65\x80\xed\x67\x83\xbf\xb5\x0a\x24\x30\x9d\x8b\x97\xd0\x8f\xb3\x93\x3c\x24\x0c\x88\xb7\x96\xc9\x8c\xb5\x17\x3a\x3a\x64\xb3\xb6\xed\x56\x80\x86\x0f\x25\x32\x87\xb9\xb7\x4d\x66\x98\xe3\x36\x3a\x0c\xb1\xba\x8e\x1d\x10\xea\x63\x33\x3f\x70\xb9\xbb\x9f\x0d\x05\xf1\x1f\x33\x36\x81\xa4\xbf\x67\x34\x06\xd5\x05\x31\x06\xb6\xa4\xb7\x0d\x33\x07\xc5\x1a\x0a\x5f\xbe\xa5\x9a\x30\x3d\x1f\xe0\x12\x06\x9a\xbb\xbf\x6b\x39\x32\x7b\x9d\x62\x14\x89\xbb\xb4\x0b\x25\x36\x97\x86\x5e\xd1\xb4\xbf\x9e\x3c\x24\x0d\x82\x8c")); +snd($sock_a, $port_b, rtp(0, 1006, 3960, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1006, 3960, $ssrc, "\xf0\xe2\xb7\xb1\x14\x3a\x3b\x61\xb6\x88\xf3\xeb\xb5\x8d\x09\x24\x32\x85\xbd\x89\x5c\xe2\x8c\x95\x30\x24\x0e\xb7\xb9\x83\x68\xc3\x85\x6e\x3f\x38\x7a\xbe\xb9\x92\x05\x7a\x95\x07\x3e\x30\x86\xa5\xbd\x7c\x0f\x15\xcb\x0d\x3d\x03\xb1\xa4\xb4\x01\x34\x11\x40\x0f\x36\x48\xb9\xa5\x85\x37\x36\x14\x45\x02\x0f\x84\xa5\xbe\x6d\x3c\x36\x7d\xf1\x04\x1c\xb5\xa5\xb7\x09\x3b\x35\xed\xea\x13\x57\xb0\xb8\x9b\x3d\x3a\x00\x84\x9e\x66\x97\xb2\xb2\x15\x3a\x38\x60\x8b\x87\x58\x98\xb0\x88\x08\x24\x32\x9e\xb1\x86\x54\x9a\xb7\x90\x32\x24\x0e\xb5\xb2\x84\x73\x9f\x8c\x68\x38\x3b\x61\xbc\xbd\x96\x14\x94\x99\x03\x3b\x32\x87\xba\xb3\x48\x1a\xf2\xe5\x0a\x39\x0c\xb1")); +snd($sock_a, $port_b, rtp(0, 1007, 4120, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1007, 4120, $ssrc, "\xa4\xb5\x1a\x02\x4c\x7f\x37\x32\x7c\xb9\xa5\x9a\x0a\x09\x7e\x6e\x34\x35\x87\xa5\xbe\x67\x33\x0b\x48\x6e\x08\x05\xb7\xa4\xb6\x0f\x3f\x0e\xfe\x79\x00\x5a\xbd\xa5\x85\x32\x39\x07\x92\xcd\x1d\x9d\xbe\xbc\x69\x3b\x3e\x60\x80\xef\x66\x80\xbf\xb5\x08\x24\x30\x90\x8b\x91\xd5\x8c\xb3\x9f\x3d\x24\x0e\x89\xb7\x91\xc2\x8c\xb5\x68\x3b\x3a\x6d\xb3\xb1\xee\x5c\x81\x81\x0c\x25\x3d\x85\xb9\xb7\x58\x60\x99\xef\x37\x3a\x0e\xb6\xba\x89\x12\x13\xeb\x67\x33\x3e\x67\xb9\xba\x98\x02\x05\xf7\x1d\x33\x36\x87\xa4\xbe\x7c\x34\x01\x54\x1a\x31\x01\xb6\xa4\xb6\x03\x33\x06\xda\x18\x0a\x75\xbf\xa5\x84\x31\x3d\x19\xe0\x10\x01\x99\xbb\xbe\x62\x39\x3d\x66\x9d\x60\x17")); +# pause +snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1008, 4280, $ssrc, "\xd5" x 160)); +snd($sock_a, $port_b, rtp(0, 1009, 4440, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1009, 4440, $ssrc, "\xd5" x 160)); +snd($sock_a, $port_b, rtp(0, 1010, 4600, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1010, 4600, $ssrc, "\xd5" x 160)); +snd($sock_a, $port_b, rtp(0, 1011, 4760, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1011, 4760, $ssrc, "\xd5" x 160)); +snd($sock_a, $port_b, rtp(0, 1012, 4920, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1012, 4920, $ssrc, "\xd5" x 160)); +snd($sock_a, $port_b, rtp(0, 1013, 5080, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(8, 1013, 5080, $ssrc, "\x2a" x 160)); + + + + +snd($sock_b, $port_a, rtp(8, 4000, 8000, 0x6543, "\x2a" x 160)); +($ssrc) = rcv($sock_a, $port_b, rtpm(0, 4000, 8000, -1, "\x00" x 160)); +snd($sock_b, $port_a, rtp(8, 4001, 8160, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4001, 8160, $ssrc, "\x00" x 160)); + +$resp = rtpe_req('play DTMF', 'inject DTMF towards A', + { 'from-tag' => tt(), code => '4', volume => 3, duration => 150 }); + +snd($sock_b, $port_a, rtp(8, 4002, 8320, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4002, 8320, $ssrc, "\xff\x90\x8a\x93\xd9\x1b\x18\x27\x65\xe5\x33\x29\x4c\x9e\x8f\x91\xb8\x15\x09\x0d\x32\x98\x8e\x96\xbb\x2c\x2b\x4c\xd8\x34\x1c\x18\x2e\x9d\x8c\x8c\xa5\x1a\x0b\x0d\x27\xa3\x97\x9e\xbd\x4f\xc4\xaa\xb2\x2c\x12\x0e\x1e\xa1\x8b\x8a\x9c\x25\x0e\x10\x25\xb7\xa7\xb7\x5e\xcb\xa2\x98\x9f\x30\x0f\x0a\x16\xae\x8d\x8a\x98\x3a\x18\x19\x2c\xdd\xfd\x30\x2b\xce\x99\x8e\x95\x4c\x0f\x09\x10\xdf\x93\x8e\x9a\xec\x28\x2c\x56\xee\x2d\x1a\x1a\x48\x97\x8b\x8e\xba\x14\x0a\x0f\x39\x9d\x96\xa1\xcd\x4e\xbe\xab\xbe\x23\x10\x10\x2b\x99\x8a\x8c\xa7\x1b\x0d\x12\x2f\xad\xa7\xbc\x5e\xbd\x9f\x99\xa8\x23\x0d\x0b\x1d\x9f\x8b\x8c\x9f\x29\x16\x1b\x34\xcd\x60\x2f\x2f\xb6\x96")); +snd($sock_b, $port_a, rtp(8, 4003, 8480, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4003, 8480, $ssrc, "\x8e\x9b\x2b\x0c\x09\x17\xae\x8f\x8e\x9e\x3f\x25\x2e\x65\x5c\x28\x1a\x1e\xc2\x92\x8a\x92\x44\x0f\x0a\x14\xd6\x99\x97\xa6\x7c\x4e\xba\xad\xe5\x1d\x0f\x13\x49\x92\x89\x8e\xbe\x15\x0d\x16\x43\xa8\xa7\xc1\x66\xb5\x9d\x9a\xb6\x1b\x0c\x0d\x2b\x98\x8a\x8d\xab\x1f\x15\x1d\x3f\xc7\x52\x2e\x39\xaa\x93\x8f\xa3\x1e\x0b\x0b\x1e\x9f\x8d\x8f\xa7\x30\x23\x31\x7c\x4a\x24\x1a\x24\xac\x8e\x8b\x99\x28\x0c\x0a\x1a\xb0\x96\x98\xac\x4f\x53\xb7\xaf\x44\x19\x0f\x18\xba\x8e\x89\x93\x3f\x10\x0d\x1a\xd5\xa3\xa8\xca\xf9\xae\x9c\x9d\xec\x16\x0b\x10\x4e\x91\x89\x90\xc6\x1a\x14\x20\x55\xc3\x4a\x2f\x49\xa2\x91\x92\xb2\x17\x09\x0c\x2d\x99\x8d\x92\xb3\x29\x23\x36\xf2")); +snd($sock_b, $port_a, rtp(8, 4004, 8640, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4004, 8640, $ssrc, "\x3e\x20\x1b\x2d\xa0\x8d\x8c\xa1\x1c\x0a\x0c\x22\xa3\x94\x9a\xb5\x44\x5c\xb5\xb6\x32\x16\x0f\x1e\xa6\x8c\x8a\x99\x28\x0e\x0e\x20\xb7\xa1\xab\xd4\xdb\xaa\x9c\xa1\x38\x11\x0b\x15\xb5\x8d\x8a\x96\x3f\x16\x15\x26\xdd\xc2\x43\x31\xdf\x9d\x90\x96\x6d\x11\x09\x0f\x5a\x93\x8c\x97\xd2\x23\x23\x3b\xf6\x37\x1f\x1d\x40\x9a\x8c\x8e\xb2\x15\x09\x0e\x31\x9c\x93\x9c\xc2\x3e\x74\xb4\xbf\x29\x14\x11\x29\x9b\x8a\x8b\xa3\x1c\x0d\x0f\x2a\xab\x9f\xad\xe0\xcc\xa6\x9c\xa9\x28\x0e\x0c\x1c\xa2\x8b\x8b\x9c\x2a\x14\x17\x2c\xc6\xc4\x3e\x36\xbd\x99\x90\x9b\x30\x0d\x09\x15\xb3\x8f\x8d\x9b\x42\x1f\x25\x42\x70\x30\x1e\x1f\xcf\x95\x8b\x92\x58\x0f\x09\x12\x6f\x98\x93")); +snd($sock_b, $port_a, rtp(8, 4005, 8800, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4005, 8800, $ssrc, "\x9f\xe5\x3b\xe2\xb5\xd9\x21\x12\x14\x3e\x95\x89\x8d\xb6\x16\x0c\x13\x3a\xa4\x9f\xb1\xf1\xc0\xa3\x9d\xb4\x1e\x0d\x0d\x27\x99\x8a\x8c\xa7\x1f\x12\x19\x37\xbc\xc8\x3c\x3c\xaf\x97\x91\xa2\x21\x0b\x0a\x1c\xa2\x8d\x8e\xa2\x2f\x1e\x28\x4c\x5d\x2c\x1e\x25\xb0\x90\x8c\x98\x2c\x0c\x0a\x18\xb4\x94\x94\xa6\x4d\x3a\xd4\xb8\x4f\x1d\x11\x18\xc5\x8f\x89\x91\x4d\x10\x0c\x17\xec\x9f\xa0\xb8\xff\xba\xa1\x9f\xd3\x19\x0c\x0f\x3f\x92\x89\x8f\xbb\x19\x11\x1c\x48\xb8\xce\x3b\x4a\xa8\x95\x93\xaf\x19\x0a\x0c\x29\x99\x8c\x8f\xad\x27\x1d\x2b\x59\x4f\x29\x1e\x2d\xa5\x8e\x8d\x9f\x1e\x0b\x0b\x1e\xa4\x91\x96\xad\x3e\x3b\xcc\xbc\x3a\x1a\x12\x1e\xaa\x8d\x8a\x98\x2b")); +snd($sock_b, $port_a, rtp(8, 4006, 8960, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4006, 8960, $ssrc, "\x0e\x0c\x1d\xb8\x9d\xa2\xbe\xf9\xb4\xa0\xa3\x3f\x14\x0c\x14\xbd\x8e\x89\x93\x49\x15\x12\x1f\xe7\xb5\xd9\x3c\x7c\xa1\x93\x97\xd5\x13\x09\x0e\x45\x93\x8b\x93\xc4\x20\x1d\x2e\x6b\x46\x26\x1f\x3d\x9d\x8d\x8e\xae\x17\x09\x0d\x2c\x9c\x90\x98\xba\x36\x3d\xc7\xc4\x2e\x17\x13\x27\x9e\x8b\x8b\x9f\x1e\x0c\x0e\x25\xaa\x9c\xa5\xc8\xe8\xae\xa0\xaa\x2d\x10\x0c\x1b\xa6\x8c\x8a\x9a\x2c\x12\x13\x27\xc3\xb3\xed\x3e\xc8\x9d\x93\x9b\x38\x0f\x09\x13\xba\x8f\x8b\x98\x4a\x1d\x1e\x34\xf9\x3e\x24\x23\xea\x98\x8c\x92\xdf\x10\x09\x0f\x4d\x97\x90\x9c\xd2\x31\x3f\xc5\xd6\x28\x16\x16\x39\x97\x8a\x8d\xaf\x17\x0b\x10\x32\xa2\x9b\xa8\xd6\xd9\xac\xa1\xb3\x22\x0e\x0e")); +snd($sock_b, $port_a, rtp(8, 4007, 9120, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4007, 9120, $ssrc, "\x24\x9b\x8a\x8b\xa2\x1f\x10\x15\x2f\xb8\xb4\x68\x43\xb8\x9a\x94\xa1\x25\x0c\x0a\x1a\xa5\x8d\x8c\x9e\x30\x1b\x1f\x3c\xee\x38\x23\x28\xb8\x93\x8d\x97\x31\x0d\x09\x15\xb9\x93\x90\xa0\x4f\x2f\x46\xc4\x5e\x21\x15\x19\xd7\x91\x89\x90\x7b\x10\x0b\x14\x5b\x9d\x9c\xad\xed\xcd\xa9\xa3\xca\x1c\x0d\x10\x38\x94\x89\x8e\xb3\x19\x0f\x18\x3e\xb0\xb5\x59\x4d\xae\x98\x95\xad\x1c\x0b\x0c\x25\x9b\x8b\x8e\xa9\x26\x1a\x22\x46\xf5\x33\x23\x2e\xaa\x90\x8d\x9e\x21\x0b\x0a\x1c\xa6\x90\x92\xa8\x3b\x2e\x4d\xc7\x43\x1e\x15\x1e\xaf\x8e\x8a\x96\x2e\x0e\x0b\x1a\xbb\x9b\x9d\xb2\x68\xc5\xa8\xa7\x4c\x17\x0d\x14\xcb\x8f\x89\x91\x5e\x14\x0f\x1c\x6e\xad\xb8\x52\x68\xa8")); +snd($sock_b, $port_a, rtp(8, 4008, 9280, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4008, 9280, $ssrc, "\x97\x98\xc7\x16\x0a\x0e\x3a\x94\x8a\x90\xbb\x1e\x1a\x27\x56\x6f\x2f\x25\x3b\xa0\x8e\x8f\xaa\x19\x09\x0c\x28\x9c\x8f\x95\xb2\x31\x2e\x59\xcc\x37\x1b\x16\x26\xa1\x8c\x8b\x9d\x1f\x0c\x0c\x20\xab\x99\x9e\xbb\x5d\xbe\xa7\xac\x32\x13\x0d\x1a\xab\x8c\x89\x97\x2e\x10\x10\x21\xc3\xab\xbc\x4f\xd4\xa2\x96\x9c\x3f\x10\x0a\x12\xc4\x8f\x8a\x95\x57\x1b\x1a\x2b\xfd\x5d\x2d\x27\x62\x9b\x8e\x92\xc9\x12\x09\x0e\x3f\x97\x8e\x98\xc6\x2c\x2f\x6b\xd9\x2e\x1a\x18\x34\x9a\x8b\x8d\xab\x18\x0a\x0e\x2d\xa1\x98\xa1\xc7\x5b\xb9\xa7\xb4\x27\x10\x0e\x22\x9d\x8a\x8b\x9f\x20\x0e\x12\x2a\xb4\xaa\xc0\x50\xc0\x9e\x97\xa1\x2a\x0e\x0a\x19\xa8\x8c\x8b\x9b\x31\x18\x1b\x31")); +snd($sock_b, $port_a, rtp(8, 4009, 9440, 0x6543, "\x2a" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4009, 9440, $ssrc, "\xda\x50\x2c\x2b\xc0\x97\x8e\x97\x39\x0e\x09\x13\xbf\x92\x8e\x9c\x57\x29\x31\xef\x72\x28\x19\x1b\x6d\x94\x8a\x8f\xce\x11\x0a\x11\x48\x9c\x98\xa5\xdc\x5e\xb5\xa9\xc6\x1f\x0f\x10\x31\x96\x89\x8d\xad\x19\x0e\x15\x37\xac\xaa\xc8\x57\xb7\x9c\x98\xac\x1e\x0c\x0c\x21\x9c\x8b\x8d\xa4\x25\x17\x1d\x3b\xcf\x48\x2b\x30\xae\x93\x8e" . "\xff" x 80)); +# pause +snd($sock_b, $port_a, rtp(0, 4010, 9600, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4010, 9600, $ssrc, "\xff" x 160)); +snd($sock_b, $port_a, rtp(0, 4011, 9760, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4011, 9760, $ssrc, "\xff" x 160)); +snd($sock_b, $port_a, rtp(0, 4012, 9920, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4012, 9920, $ssrc, "\xff" x 160)); +snd($sock_b, $port_a, rtp(0, 4013, 10080, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4013, 10080, $ssrc, "\xff" x 160)); +snd($sock_b, $port_a, rtp(0, 4014, 10240, 0x6543, "\x00" x 160)); +rcv($sock_a, $port_b, rtpm(0, 4014, 10240, $ssrc, "\xff" x 80 . "\x00" x 80)); + + + + +# multiple consecutive DTMF events -offer('ICE SDP with ICE force', { ICE => 'force' }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'optional' }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'force' }, < ft(), code => 'C', volume => 5, duration => 100 }); +$resp = rtpe_req('play DTMF', 'inject DTMF towards B', + { 'from-tag' => ft(), code => '4', volume => 5, duration => 100 }); -answer('ICE SDP, no ICE option given', { ICE => 'optional' }, < 'force' }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < 'force' }, < 'remove', replace => ['origin'], flags => ['inject DTMF'] }, < ft(), code => '0', volume => 10, duration => 100 }); +$resp = rtpe_req('play DTMF', 'inject DTMF towards B', + { 'from-tag' => ft(), code => '1', volume => 6, duration => 100 }); + +snd($sock_a, $port_b, rtp(0, 1002, 3320, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96 | 0x80, 1002, 3320, $ssrc, "\x00\x0a\x00\xa0")); +snd($sock_a, $port_b, rtp(0, 1003, 3480, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1003, 3320, $ssrc, "\x00\x0a\x01\x40")); +snd($sock_a, $port_b, rtp(0, 1004, 3640, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1004, 3320, $ssrc, "\x00\x0a\x01\xe0")); +snd($sock_a, $port_b, rtp(0, 1005, 3800, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1005, 3320, $ssrc, "\x00\x0a\x02\x80")); +snd($sock_a, $port_b, rtp(0, 1006, 3960, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1006, 3320, $ssrc, "\x00\x0a\x03\x20")); +snd($sock_a, $port_b, rtp(0, 1007, 4120, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1007, 3320, $ssrc, "\x00\x8a\x03\xc0")); +rcv($sock_b, $port_a, rtpm(96, 1008, 3320, $ssrc, "\x00\x8a\x03\xc0")); +rcv($sock_b, $port_a, rtpm(96, 1009, 3320, $ssrc, "\x00\x8a\x03\xc0")); +snd($sock_a, $port_b, rtp(0, 1008, 4280, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1010, 4280, $ssrc, "\x00" x 160)); +snd($sock_a, $port_b, rtp(0, 1009, 4440, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1011, 4440, $ssrc, "\x00" x 160)); +snd($sock_a, $port_b, rtp(0, 1010, 4600, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1012, 4600, $ssrc, "\x00" x 160)); +snd($sock_a, $port_b, rtp(0, 1011, 4760, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1013, 4760, $ssrc, "\x00" x 160)); +snd($sock_a, $port_b, rtp(0, 1012, 4920, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96 | 0x80, 1014, 4920, $ssrc, "\x01\x06\x00\xa0")); +snd($sock_a, $port_b, rtp(0, 1013, 5080, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1015, 4920, $ssrc, "\x01\x06\x01\x40")); +snd($sock_a, $port_b, rtp(0, 1014, 5240, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1016, 4920, $ssrc, "\x01\x06\x01\xe0")); +snd($sock_a, $port_b, rtp(0, 1015, 5400, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1017, 4920, $ssrc, "\x01\x06\x02\x80")); +snd($sock_a, $port_b, rtp(0, 1016, 5560, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1018, 4920, $ssrc, "\x01\x06\x03\x20")); +snd($sock_a, $port_b, rtp(0, 1017, 5720, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(96, 1019, 4920, $ssrc, "\x01\x86\x03\xc0")); +rcv($sock_b, $port_a, rtpm(96, 1020, 4920, $ssrc, "\x01\x86\x03\xc0")); +rcv($sock_b, $port_a, rtpm(96, 1021, 4920, $ssrc, "\x01\x86\x03\xc0")); +snd($sock_a, $port_b, rtp(0, 1018, 5880, 0x1234, "\x00" x 160)); +rcv($sock_b, $port_a, rtpm(0, 1022, 5880, $ssrc, "\x00" x 160)); + + + + + +# SDP in/out tests, various ICE options + new_call; -offer('ICE SDP with ICE default', { ICE => 'default' }, < 'remove' }, < 'default' }, < 'remove' }, < 'default' }, < 'default' }, < 'force' }, < 'optional' }, < 'remove' }, < 'remove' }, < 'force' }, < 'optional' }, < '3.4.5.6', + flags => ['full-rtcp-attribute'], ICE => 'optional', }, < 'optional' }, < 'remove' }, < 'optional' }, < 'remove', DTLS => 'off' }, < 'force' }, < 'remove' }, < 'optional' }, < 'remove', DTLS => 'off', SDES => [ 'no-F8_128_HMAC_SHA1_80' ] }, < 'force' }, < 'remove' }, < 'optional' }, < 'remove', DTLS => 'off', SDES => [ 'no-AES_CM_128_HMAC_SHA1_32' ] }, < 'force' }, < 'remove' }, < 'force' }, < 'remove', DTLS => 'off', SDES => [ 'no-AES_CM_128_HMAC_SHA1_80' ] }, < 'default' }, < 'remove' }, < 'default' }, < 'remove', DTLS => 'off', 'transport protocol' => 'RTP/AVP' }, < 'default' }, < 'remove' }, < 'remove', DTLS => 'off', 'transport protocol' => 'RTP/AVP', SDES => [ 'no-AES_CM_128_HMAC_SHA1_32' ] }, < 'remove' }, < 'remove', DTLS => 'off', 'transport protocol' => 'RTP/AVP', SDES => [ 'no-AES_CM_128_HMAC_SHA1_80' ] }, < 'force' }, < 'remove' }, < 'remove', DTLS => 'off', 'transport protocol' => 'RTP/SAVP' }, < 'remove' }, < 'remove', DTLS => 'off', 'transport protocol' => 'RTP/SAVP', SDES => [ 'no-F8_128_HMAC_SHA1_80' ] }, < 'force' }, < 'remove' }, < 'remove', DTLS => 'off', 'transport protocol' => 'RTP/SAVP', SDES => [ 'no-AES_CM_128_HMAC_SHA1_80' ] }, < 'remove' }, < 'remove' }, < 'remove', replace => ['origin'], DTLS => 'off' }, < ['origin'] }, < ft(), blob => $wav_file }); -is $resp->{duration}, 100, 'media duration'; - -my $srtp_ctx = { - cs => $NGCP::Rtpclient::SRTP::crypto_suites{AES_CM_128_HMAC_SHA1_80}, - key => 'DVM+BTeYX2UI1LaA9bgXrcBEDBxoItA9/39fSoRF', -}; -(undef, $seq, $ts, $ssrc) = srtp_rcv($sock_a, -1, rtpm(8 | 0x80, -1, -1, -1, $pcma_1), $srtp_ctx); -srtp_rcv($sock_a, -1, rtpm(8, $seq + 1, $ts + 160 * 1, $ssrc, $pcma_2), $srtp_ctx); -srtp_rcv($sock_a, -1, rtpm(8, $seq + 2, $ts + 160 * 2, $ssrc, $pcma_3), $srtp_ctx); -srtp_rcv($sock_a, -1, rtpm(8, $seq + 3, $ts + 160 * 3, $ssrc, $pcma_4), $srtp_ctx); -srtp_rcv($sock_a, -1, rtpm(8, $seq + 4, $ts + 160 * 4, $ssrc, $pcma_5), $srtp_ctx); - - - - - - # ptime tests ($sock_a, $sock_b) = new_call([qw(198.51.100.1 3000)], [qw(198.51.100.3 3002)]); diff --git a/t/auto-daemon-tests.pl b/t/auto-daemon-tests.pl index 5789e39bc..8f59aa831 100755 --- a/t/auto-daemon-tests.pl +++ b/t/auto-daemon-tests.pl @@ -3981,10 +3981,12 @@ a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192 a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192 a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256 a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256 -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 a=setup:actpass a=fingerprint:sha-1 FINGERPRINT SDP @@ -4024,10 +4026,12 @@ a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192 a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192 a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256 a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256 -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 a=setup:actpass a=fingerprint:sha-1 FINGERPRINT SDP @@ -4073,10 +4077,12 @@ a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192 a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192 a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256 a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256 -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 SDP answer('stray answer protocol changes, default', { @@ -4148,10 +4154,12 @@ a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192 a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192 a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256 a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256 -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 SDP answer('stray answer protocol changes, proto accept', { @@ -4224,10 +4232,12 @@ a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192 a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192 a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256 a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256 -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 SDP answer('stray answer protocol changes, proto accept', { @@ -4595,10 +4605,12 @@ a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192 a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192 a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256 a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256 -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 a=setup:actpass a=fingerprint:sha-1 FINGERPRINT a=ptime:20 @@ -4711,10 +4723,12 @@ a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192 a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192 a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256 a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256 -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 a=setup:actpass a=fingerprint:sha-1 FINGERPRINT a=ptime:20 @@ -4842,10 +4856,12 @@ a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192 a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192 a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256 a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256 -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 a=ptime:20 SDP @@ -4936,10 +4952,12 @@ a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192 a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192 a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256 a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256 -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 a=ptime:20 SDP @@ -5034,10 +5052,12 @@ a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192 a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192 a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256 a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256 -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 a=ptime:20 SDP @@ -5094,10 +5114,12 @@ a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192 a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192 a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256 a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256 -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 a=ptime:20 SDP @@ -5331,10 +5353,12 @@ a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192 a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192 a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256 a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256 -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 SDP ($port_b, undef, $srtp_key_b) = answer('reg SRTP offer, accept, diff suite', @@ -5416,10 +5440,12 @@ a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192 a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192 a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256 a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256 -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 SDP ($port_b) = answer('OSRTP offer, accept, same suite', @@ -5489,10 +5515,12 @@ a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192 a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192 a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256 a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256 -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 SDP ($port_b, undef, $srtp_key_b) = answer('OSRTP offer, accept, diff suite', @@ -5571,10 +5599,12 @@ a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192 a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192 a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256 a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256 -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 SDP ($port_b) = answer('OSRTP offer, reject', @@ -5633,10 +5663,12 @@ a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192 a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192 a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256 a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256 -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 SDP ($port_b, undef, $srtp_key_a) = answer('OSRTP offer, reject w/ accept flag', @@ -5706,10 +5738,12 @@ a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192 a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192 a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256 a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256 -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 SDP ($port_b) = answer('non-OSRTP offer with offer flag, accept', @@ -5779,10 +5813,12 @@ a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192 a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192 a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256 a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256 -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 SDP ($port_b) = answer('non-OSRTP offer with offer flag and protocol, accept', @@ -5853,10 +5889,12 @@ a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192 a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192 a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256 a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256 -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 SDP ($port_b) = answer('non-OSRTP offer with offer flag, reject', @@ -6040,10 +6078,12 @@ a=crypto:3 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192|2^31 a=crypto:4 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192|2^31 a=crypto:5 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256|2^31 a=crypto:6 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256|2^31 -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128|2^31 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128|2^31 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128|2^31 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128|2^31 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S|2^31 +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S|2^31 +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128|2^31 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128|2^31 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128|2^31 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128|2^31 SDP @@ -7498,10 +7538,12 @@ a=crypto:5 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192= a=crypto:6 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192= a=crypto:7 AES_256_CM_HMAC_SHA1_80 inline:CRYPTO256== a=crypto:8 AES_256_CM_HMAC_SHA1_32 inline:CRYPTO256== -a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:9 AEAD_AES_128_GCM inline:CRYPTO128S== +a=crypto:10 AEAD_AES_256_GCM inline:CRYPTO256S= +a=crypto:11 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:13 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:14 NULL_HMAC_SHA1_32 inline:CRYPTO128 SDP ($port_b) = answer('gh829 control', @@ -7573,10 +7615,12 @@ a=crypto:3 AES_CM_128_HMAC_SHA1_80 inline:Qk0TvVeyfqfjFd/YebnyyklqSEhJntpVKV1KAh a=crypto:4 AES_CM_128_HMAC_SHA1_32 inline:Kl3GFJ5Gqz5x07xYkoyHODkVkSpiplZnXsQIw+Q? a=crypto:5 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192= a=crypto:6 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192= -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S== +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S= +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 SDP ($port_b) = answer('gh829', @@ -9102,10 +9146,12 @@ a=crypto:3 AES_256_CM_HMAC_SHA1_80 inline:8AbZePWwsKhLGX3GlXA+yHYPQ3cgraer/9DkFJ a=crypto:4 AES_256_CM_HMAC_SHA1_32 inline:2GLk3p/csdno4KlGO1TxCVaEt+bifmDlQ5NjnCb5cJYPURiGRSTBEtEq37db8? a=crypto:5 AES_192_CM_HMAC_SHA1_80 inline:CRYPTO192 a=crypto:6 AES_192_CM_HMAC_SHA1_32 inline:CRYPTO192 -a=crypto:7 F8_128_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:8 F8_128_HMAC_SHA1_32 inline:CRYPTO128 -a=crypto:9 NULL_HMAC_SHA1_80 inline:CRYPTO128 -a=crypto:10 NULL_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:7 AEAD_AES_128_GCM inline:CRYPTO128S +a=crypto:8 AEAD_AES_256_GCM inline:CRYPTO256S +a=crypto:9 F8_128_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:10 F8_128_HMAC_SHA1_32 inline:CRYPTO128 +a=crypto:11 NULL_HMAC_SHA1_80 inline:CRYPTO128 +a=crypto:12 NULL_HMAC_SHA1_32 inline:CRYPTO128 SDP answer('gh 661 plain', { ICE => 'remove' }, < 'remove' }, < 'remove' }, < 'remove' }, < 'remove' }, < 'remove' }, < 'remove' }, < ['origin'] }, <