diff options
Diffstat (limited to 'staging/cli_rtp.c')
-rw-r--r-- | staging/cli_rtp.c | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/staging/cli_rtp.c b/staging/cli_rtp.c new file mode 100644 index 0000000..28a6c2b --- /dev/null +++ b/staging/cli_rtp.c @@ -0,0 +1,343 @@ +/* + * Mausezahn - A fast versatile traffic generator + * Copyright (C) 2008-2010 Herbert Haas + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see http://www.gnu.org/licenses/gpl-2.0.html + * +*/ + + + +#include "mz.h" +#include "cli.h" +#include "mops.h" + + +int cmd_rtp_version (struct cli_def *cli, const char *command, char *argv[], int argc) +{ + struct mops_ext_rtp * pd = clipkt->p_desc; + int v=2; + + if ( (strcmp(argv[argc-1],"?")==0) || (argc!=1)) { + cli_print(cli, "Set the RTP version (0..3, default: v2).\n"); + return CLI_OK; + } + if (mz_strisnum(argv[0])==0) { + cli_print(cli, "Invalid number.\n"); + return CLI_OK; + } + v = (int) str2int(argv[0]); + if (v>3) { + cli_print(cli, "Range exceeded (0..3).\n"); + return CLI_OK; + } + pd->v = v; + return CLI_OK; +} + +int cmd_rtp_padding (struct cli_def *cli, const char *command, char *argv[], int argc) +{ + struct mops_ext_rtp * pd = clipkt->p_desc; + char state[8]; + + if ( (strcmp(argv[argc-1],"?")==0) || (argc!=1)) { + cli_print(cli, "Sets or unsets the RTP padding flag (default: disabled).\n"); + cli_print(cli, "Use the keywords 'set' or 'unset'.\n"); + sprintf(state, "%s", (pd->p) ? "SET" : "UNSET"); + cli_print(cli, "Current state of the padding flag: %s\n",state); + return CLI_OK; + } + + if (mz_strcmp(argv[0], "set", 1)==0) { + pd->p = 1; + } else if (mz_strcmp(argv[0], "unset", 1)==0) { + pd->p = 0; + } + else { + cli_print(cli, "Invalid keyword. Use 'set' or 'unset'.\n"); + } + + return CLI_OK; +} + +int cmd_rtp_xten (struct cli_def *cli, const char *command, char *argv[], int argc) +{ + struct mops_ext_rtp * pd = clipkt->p_desc; + char state[8]; + + if ( (strcmp(argv[argc-1],"?")==0) || (argc!=1)) { + cli_print(cli, "Sets or unsets the RTP extension flag (default: disabled).\n"); + cli_print(cli, "NOTE: This command only sets the extension flag in the RTP header.\r"); + cli_print(cli, "If you really want an extension header use the 'extension' command.\n"); + cli_print(cli, "Use the keywords 'set' or 'unset'.\n"); + sprintf(state, "%s", (pd->x) ? "SET" : "UNSET"); + cli_print(cli, "Current state of the extension flag: %s\n",state); + return CLI_OK; + } + + if (mz_strcmp(argv[0], "set", 1)==0) { + pd->x = 1; + } else if (mz_strcmp(argv[0], "unset", 1)==0) { + pd->x = 0; + } + else { + cli_print(cli, "Invalid keyword. Use 'set' or 'unset'.\n"); + } + + return CLI_OK; +} + + +int cmd_rtp_marker (struct cli_def *cli, const char *command, char *argv[], int argc) +{ + struct mops_ext_rtp * pd = clipkt->p_desc; + char state[8]; + + if ( (strcmp(argv[argc-1],"?")==0) || (argc!=1)) { + cli_print(cli, "Sets or unsets the RTP marker flag (default: disabled).\n"); + cli_print(cli, "Use the keywords 'set' or 'unset'.\n"); + sprintf(state, "%s", (pd->m) ? "SET" : "UNSET"); + cli_print(cli, "Current state of the marker flag: %s\n",state); + return CLI_OK; + } + if (mz_strcmp(argv[0], "set", 1)==0) { + pd->m = 1; + } else if (mz_strcmp(argv[0], "unset", 1)==0) { + pd->m = 0; + } + else { + cli_print(cli, "Invalid keyword. Use 'set' or 'unset'.\n"); + } + return CLI_OK; +} + + +int cmd_rtp_cc (struct cli_def *cli, const char *command, char *argv[], int argc) +{ + struct mops_ext_rtp * pd = clipkt->p_desc; + int cc=0; + + if ( (strcmp(argv[argc-1],"?")==0) || (argc!=1)) { + cli_print(cli, "Configure the RTP CSRC count (0..15, default: 0).\n"); + cli_print(cli, "NOTE: This command only configures the CSRC value in the RTP header.\r"); + cli_print(cli, "If you want to add a valid CSRC list use the 'csrc-list' command.\r"); + cli_print(cli, "The main purpose of this command is to create an invalid RTP packet.\r"); + return CLI_OK; + } + if (mz_strisnum(argv[0])==0) { + cli_print(cli, "Invalid number.\n"); + return CLI_OK; + } + cc = (int) str2int(argv[0]); + if (cc>15) { + cli_print(cli, "Range exceeded (0..15).\n"); + return CLI_OK; + } + pd->cc = cc; + return CLI_OK; +} + + +int cmd_rtp_pt (struct cli_def *cli, const char *command, char *argv[], int argc) +{ + struct mops_ext_rtp * pd = clipkt->p_desc; + int pt=0; + + if ( (strcmp(argv[argc-1],"?")==0) || (argc!=1)) { + cli_print(cli, "Configure the RTP payload type (0..127, default: 8 (G.711, A-law)).\n"); + // TODO: provide a list with well-known PT values + return CLI_OK; + } + if (mz_strisnum(argv[0])==0) { + cli_print(cli, "Invalid number.\n"); + return CLI_OK; + } + pt = (int) str2int(argv[0]); + if (pt>127) { + cli_print(cli, "Range exceeded (0..127).\n"); + return CLI_OK; + } + pd->pt = pt; + return CLI_OK; +} + +int cmd_rtp_ssrc (struct cli_def *cli, const char *command, char *argv[], int argc) +{ + struct mops_ext_rtp * pd = clipkt->p_desc; + unsigned long long int ssrc = 0xcafefeed; + + if ( (strcmp(argv[argc-1],"?")==0) || (argc!=1)) { + cli_print(cli, "Configure the RTP SSRC (source identifier) (0..ffffffff, default: random!).\n"); + cli_print(cli, "NOTE: The SSRC value is used by another Mausezahn receiver to identify a original\r"); + cli_print(cli, "Mausezahn RTP stream. By default, Mausezahn receivers check for the magic number\r"); + cli_print(cli, "'cafebabe' (hex). Use another number for another RTP stream (e. g. bidirectional\r"); + cli_print(cli, "measurements).\n"); + return CLI_OK; + } + + if (mz_strishex(argv[0])==0) { + cli_print(cli, "Invalid number.\n"); + return CLI_OK; + } + + ssrc = xstr2lint(argv[0]); + if (ssrc>0xffffffff) { + cli_print(cli, "Range exceeded (0..ffffffff).\n"); + return CLI_OK; + } + pd->ssrc = (u_int32_t) ssrc; + return CLI_OK; +} + + +int cmd_rtp_sqnr (struct cli_def *cli, const char *command, char *argv[], int argc) +{ + struct mops_ext_rtp * pd = clipkt->p_desc; + unsigned long long int sqnr = 0; + + if ( (strcmp(argv[argc-1],"?")==0) || (argc!=1)) { + cli_print(cli, "Configure the RTP initial sequence number (0..ffffffff, default: 0).\n"); + return CLI_OK; + } + + if (mz_strishex(argv[0])==0) { + cli_print(cli, "Invalid number.\n"); + return CLI_OK; + } + sqnr = xstr2lint(argv[0]); + if (sqnr>0xffffffff) { + cli_print(cli, "Range exceeded (0..ffffffff).\n"); + return CLI_OK; + } + pd->sqnr = (u_int32_t) sqnr; + return CLI_OK; +} + + +int cmd_rtp_time (struct cli_def *cli, const char *command, char *argv[], int argc) +{ + struct mops_ext_rtp * pd = clipkt->p_desc; + unsigned long long int t = 0; + + if ( (strcmp(argv[argc-1],"?")==0) || (argc!=1)) { + cli_print(cli, "Configure the RTP initial timestamp (0..ffffffff, default: 0).\n"); + return CLI_OK; + } + + if (mz_strishex(argv[0])==0) { + cli_print(cli, "Invalid number.\n"); + return CLI_OK; + } + t = xstr2lint(argv[0]); + if (t>0xffffffff) { + cli_print(cli, "Range exceeded (0..ffffffff).\n"); + return CLI_OK; + } + pd->tst = (u_int32_t) t; + return CLI_OK; +} + + +int cmd_rtp_extension (struct cli_def *cli, const char *command, char *argv[], int argc) +{ + struct mops_ext_rtp * pd = clipkt->p_desc; + + if ( (strcmp(argv[argc-1],"?")==0) || (argc!=1)) { + cli_print(cli, "Configure an RTP extension header (default: none).\n"); + cli_print(cli, "Currently supported RTP extension headers:\n"); + cli_print(cli, "none Don't use any extension.\r"); + cli_print(cli, "mausezahn Use the new Mausezahn jitter/RTT measurement extension.\r"); + cli_print(cli, " (Note that this is incompatible with Mausezahn's direct\r"); + cli_print(cli, " mode jitter measurement.)\r"); + cli_print(cli, "\n"); + return CLI_OK; + } + + if (mz_strcmp(argv[0], "none", 1)==0) { + pd->x_type = 0; + pd->x = 0; // X bit in header + } else if (mz_strcmp(argv[0], "mausezahn", 1)==0) { + pd->x_type = 42; + pd->x = 1; // X bit in header + pd->ssrc = 0xcafefeed; + } else { + cli_print(cli, "Unknown keyword.\n"); + return CLI_OK; + + } + + mops_update_rtp (clipkt); // re-build RTP packet (for proper show commands) + return CLI_OK; +} + + + +int cmd_rtp_source (struct cli_def *cli, const char *command, char *argv[], int argc) +{ +// struct mops_ext_rtp * pd = clipkt->p_desc; + + if ( (strcmp(argv[argc-1],"?")==0) || (argc!=1)) { + cli_print(cli, "Specify a RTP media source.\n"); + return CLI_OK; + } + + // [TODO] -- Allow to use /dev/dsp or a mixer source ... + // + cli_print(cli, "Currently not supported.\n"); + + return CLI_OK; +} + + +int cmd_rtp_cclist (struct cli_def *cli, const char *command, char *argv[], int argc) +{ + struct mops_ext_rtp * pd = clipkt->p_desc; + unsigned long long int csrc=0; + char str[80]; + int i=0, n=0; + + + if ((strcmp(argv[argc-1],"?")==0) || (argc==0)) { + cli_print(cli, "Specify a CSRC list consisting of 1-15 CSRC values.\r"); + cli_print(cli, "Each CSRC is a 4-byte value and must be specified in hexadecimal notation,\r"); + cli_print(cli, "hence each value must be within 0..ffffffff.\n"); + return CLI_OK; + } + + if ((n=argc)>15) { + cli_print(cli, "The CSRC list must not exceed 15 items!\n"); + return CLI_OK; + } + + for (i=0; i<n; i++) { + if (mz_strishex(argv[i])==0) { + sprintf(str, "Parameter %i: Invalid number!", i); + cli_print(cli, "%s\n", str); + return CLI_OK; + } + csrc = xstr2lint(argv[i]); + if (csrc>0xffffffff) { + sprintf(str, "Parameter %i: Range exceeded (0..ffffffff)", i); + cli_print(cli, "%s\n", str); + return CLI_OK; + } + pd->csrc[i] = (u_int32_t) csrc; + } + pd->cc = n; // this one can be accessed and modified to "wrong" values by the user + pd->cc_real = n; + + return CLI_OK; +} + + + |