sgsnemu support for QoS as defined in 3GPP TS 24.008
this patch allows to tweak any bit of the QoS field of the Create PDP context generated by sgsnemu , aligned with 10.5.6.5 of 3GPP TS 24.008 V10.0.0 (2010-09) QoS field can be extended to "lenght 12" with option --qose1, as seen in real life on UMTS networks. extension to lenght 13, 15 and 17 can be done with option --qose2, --qose3, --qose4, never seen IRL but allows to test 3GPP compliance of GGSN. Signed-off-by: Yann BONNAMY <yann_bonnamy@yahoo.fr>
This commit is contained in:
parent
ad18ccb9df
commit
11a398fbc3
|
@ -47,7 +47,11 @@ const char *gengetopt_args_info_help[] = {
|
|||
" -i, --imsi=STRING IMSI (default=`240010123456789')",
|
||||
" --nsapi=INT NSAPI (default=`0')",
|
||||
" -m, --msisdn=STRING Mobile Station ISDN number (default=`46702123456')",
|
||||
" -q, --qos=INT Requested quality of service (default=`0x0b921f')",
|
||||
" -q, --qos=INT Requested quality of service (default=`0x000b921f')",
|
||||
" --qose1=INT Requested quality of service Extension 1 (example=`0x9396404074f9ffff')",
|
||||
" --qose2=INT Requested quality of service Extension 2 (example=`0x11')",
|
||||
" --qose3=INT Requested quality of service Extension 3 (example=`0x0101')",
|
||||
" --qose4=INT Requested quality of service Extension 4 (example=`0x4040')",
|
||||
" --charging=INT Charging characteristics (default=`0x0800')",
|
||||
" -u, --uid=STRING Login user ID (default=`mig')",
|
||||
" -p, --pwd=STRING Login password (default=`hemmelig')",
|
||||
|
@ -125,6 +129,10 @@ void clear_given (struct gengetopt_args_info *args_info)
|
|||
args_info->nsapi_given = 0 ;
|
||||
args_info->msisdn_given = 0 ;
|
||||
args_info->qos_given = 0 ;
|
||||
args_info->qose1_given = 0 ;
|
||||
args_info->qose2_given = 0 ;
|
||||
args_info->qose3_given = 0 ;
|
||||
args_info->qose4_given = 0 ;
|
||||
args_info->charging_given = 0 ;
|
||||
args_info->uid_given = 0 ;
|
||||
args_info->pwd_given = 0 ;
|
||||
|
@ -180,8 +188,16 @@ void clear_args (struct gengetopt_args_info *args_info)
|
|||
args_info->nsapi_orig = NULL;
|
||||
args_info->msisdn_arg = gengetopt_strdup ("46702123456");
|
||||
args_info->msisdn_orig = NULL;
|
||||
args_info->qos_arg = 0x0b921f;
|
||||
args_info->qos_arg = 0x000b921f;
|
||||
args_info->qos_orig = NULL;
|
||||
args_info->qose1_arg = 0x9396404074f9ffff;
|
||||
args_info->qose1_orig = NULL;
|
||||
args_info->qose2_arg = 0x11;
|
||||
args_info->qose2_orig = NULL;
|
||||
args_info->qose3_arg = 0x0101;
|
||||
args_info->qose3_orig = NULL;
|
||||
args_info->qose4_arg = 0x4040;
|
||||
args_info->qose4_orig = NULL;
|
||||
args_info->charging_arg = 0x0800;
|
||||
args_info->charging_orig = NULL;
|
||||
args_info->uid_arg = gengetopt_strdup ("mig");
|
||||
|
@ -792,6 +808,10 @@ cmdline_parser_internal (int argc, char * const *argv, struct gengetopt_args_inf
|
|||
{ "nsapi", 1, NULL, 0 },
|
||||
{ "msisdn", 1, NULL, 'm' },
|
||||
{ "qos", 1, NULL, 'q' },
|
||||
{ "qose1", 1, NULL, 0 },
|
||||
{ "qose2", 1, NULL, 0 },
|
||||
{ "qose3", 1, NULL, 0 },
|
||||
{ "qose4", 1, NULL, 0 },
|
||||
{ "charging", 1, NULL, 0 },
|
||||
{ "uid", 1, NULL, 'u' },
|
||||
{ "pwd", 1, NULL, 'p' },
|
||||
|
@ -1163,6 +1183,82 @@ cmdline_parser_internal (int argc, char * const *argv, struct gengetopt_args_inf
|
|||
free (args_info->selmode_orig); /* free previous string */
|
||||
args_info->selmode_orig = gengetopt_strdup (optarg);
|
||||
}
|
||||
/* QoS Extension 1. */
|
||||
else if (strcmp (long_options[option_index].name, "qose1") == 0)
|
||||
{
|
||||
if (args_info->qose1_given)
|
||||
{
|
||||
fprintf (stderr, "%s: `--qose1' option given more than once\n", PACKAGE);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
args_info->qose1_given = 1;
|
||||
args_info->qose1_arg = strtoull (optarg, &stop_char, 0);
|
||||
if (!(stop_char && *stop_char == '\0')) {
|
||||
fprintf(stderr, "%s: invalid numeric value: %s\n", argv[0], optarg);
|
||||
goto failure;
|
||||
}
|
||||
if (args_info->qose1_orig)
|
||||
free (args_info->qose1_orig); /* free previous string */
|
||||
args_info->qose1_orig = gengetopt_strdup (optarg);
|
||||
break;
|
||||
}
|
||||
/* QoS Extension 2. */
|
||||
else if (strcmp (long_options[option_index].name, "qose2") == 0)
|
||||
{
|
||||
if (args_info->qose2_given)
|
||||
{
|
||||
fprintf (stderr, "%s: `--qose2' option given more than once\n", PACKAGE);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
args_info->qose2_given = 1;
|
||||
args_info->qose2_arg = strtol (optarg, &stop_char, 0);
|
||||
if (!(stop_char && *stop_char == '\0')) {
|
||||
fprintf(stderr, "%s: invalid numeric value: %s\n", argv[0], optarg);
|
||||
goto failure;
|
||||
}
|
||||
if (args_info->qose2_orig)
|
||||
free (args_info->qose2_orig); /* free previous string */
|
||||
args_info->qose2_orig = gengetopt_strdup (optarg);
|
||||
break;
|
||||
}
|
||||
/* QoS Extension 3. */
|
||||
else if (strcmp (long_options[option_index].name, "qose3") == 0)
|
||||
{
|
||||
if (args_info->qose3_given)
|
||||
{
|
||||
fprintf (stderr, "%s: `--qose3' option given more than once\n", PACKAGE);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
args_info->qose3_given = 1;
|
||||
args_info->qose3_arg = strtol (optarg, &stop_char, 0);
|
||||
if (!(stop_char && *stop_char == '\0')) {
|
||||
fprintf(stderr, "%s: invalid numeric value: %s\n", argv[0], optarg);
|
||||
goto failure;
|
||||
}
|
||||
if (args_info->qose3_orig)
|
||||
free (args_info->qose3_orig); /* free previous string */
|
||||
args_info->qose3_orig = gengetopt_strdup (optarg);
|
||||
break;
|
||||
}
|
||||
/* QoS Extension 4. */
|
||||
else if (strcmp (long_options[option_index].name, "qose4") == 0)
|
||||
{
|
||||
if (args_info->qose4_given)
|
||||
{
|
||||
fprintf (stderr, "%s: `--qose4' option given more than once\n", PACKAGE);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
args_info->qose4_given = 1;
|
||||
args_info->qose4_arg = strtol (optarg, &stop_char, 0);
|
||||
if (!(stop_char && *stop_char == '\0')) {
|
||||
fprintf(stderr, "%s: invalid numeric value: %s\n", argv[0], optarg);
|
||||
goto failure;
|
||||
}
|
||||
if (args_info->qose4_orig)
|
||||
free (args_info->qose4_orig); /* free previous string */
|
||||
args_info->qose4_orig = gengetopt_strdup (optarg);
|
||||
break;
|
||||
}
|
||||
/* Radio Access Technology Type. */
|
||||
else if (strcmp (long_options[option_index].name, "rattype") == 0)
|
||||
{
|
||||
|
|
|
@ -85,6 +85,14 @@ struct gengetopt_args_info
|
|||
int qos_arg; /* Requested quality of service (default='0x0b921f'). */
|
||||
char * qos_orig; /* Requested quality of service original value given at command line. */
|
||||
const char *qos_help; /* Requested quality of service help description. */
|
||||
unsigned long long int qose1_arg; /* Requested quality of service Extension 1 */
|
||||
char * qose1_orig; /* Requested quality of service Extension 1 original value given at command line. */
|
||||
int qose2_arg; /* Requested quality of service Extension 2 */
|
||||
char * qose2_orig; /* Requested quality of service Extension 2 original value given at command line. */
|
||||
int qose3_arg; /* Requested quality of service Extension 3 */
|
||||
char * qose3_orig; /* Requested quality of service Extension 3 original value given at command line. */
|
||||
int qose4_arg; /* Requested quality of service Extension 4 */
|
||||
char * qose4_orig; /* Requested quality of service Extension 4 original value given at command line. */
|
||||
int charging_arg; /* Charging characteristics (default='0x0800'). */
|
||||
char * charging_orig; /* Charging characteristics original value given at command line. */
|
||||
const char *charging_help; /* Charging characteristics help description. */
|
||||
|
@ -144,6 +152,10 @@ struct gengetopt_args_info
|
|||
int nsapi_given ; /* Whether nsapi was given. */
|
||||
int msisdn_given ; /* Whether msisdn was given. */
|
||||
int qos_given ; /* Whether qos was given. */
|
||||
int qose1_given ; /* Whether qos Extension 1 was given. */
|
||||
int qose2_given ; /* Whether qos Extension 2 was given. */
|
||||
int qose3_given ; /* Whether qos Extension 3 was given. */
|
||||
int qose4_given ; /* Whether qos Extension 4 was given. */
|
||||
int charging_given ; /* Whether charging was given. */
|
||||
int uid_given ; /* Whether uid was given. */
|
||||
int pwd_given ; /* Whether pwd was given. */
|
||||
|
|
|
@ -246,6 +246,10 @@ int process_options(int argc, char **argv) {
|
|||
printf("debug: %d\n", args_info.debug_flag);
|
||||
if (args_info.imsi_arg) printf("imsi: %s\n", args_info.imsi_arg);
|
||||
printf("qos: %#08x\n", args_info.qos_arg);
|
||||
printf("qose1: %#0.16llx\n", args_info.qose1_arg);
|
||||
printf("qose2: %#04x\n", args_info.qose2_arg);
|
||||
printf("qose3: %#06x\n", args_info.qose3_arg);
|
||||
printf("qose4: %#06x\n", args_info.qose4_arg);
|
||||
printf("charging: %#04x\n", args_info.charging_arg);
|
||||
if (args_info.apn_arg) printf("apn: %s\n", args_info.apn_arg);
|
||||
if (args_info.msisdn_arg) printf("msisdn: %s\n", args_info.msisdn_arg);
|
||||
|
@ -280,6 +284,10 @@ int process_options(int argc, char **argv) {
|
|||
printf("debug: %d\n", args_info.debug_flag);
|
||||
if (args_info.imsi_arg) printf("imsi: %s\n", args_info.imsi_arg);
|
||||
printf("qos: %#08x\n", args_info.qos_arg);
|
||||
printf("qose1: %#0.16llx\n", args_info.qose1_arg);
|
||||
printf("qose2: %#04x\n", args_info.qose2_arg);
|
||||
printf("qose3: %#06x\n", args_info.qose3_arg);
|
||||
printf("qose4: %#06x\n", args_info.qose4_arg);
|
||||
printf("charging: %#04x\n", args_info.charging_arg);
|
||||
if (args_info.apn_arg) printf("apn: %s\n", args_info.apn_arg);
|
||||
if (args_info.msisdn_arg) printf("msisdn: %s\n", args_info.msisdn_arg);
|
||||
|
@ -431,10 +439,37 @@ int process_options(int argc, char **argv) {
|
|||
|
||||
|
||||
/* qos */
|
||||
options.qos.l = 3;
|
||||
options.qos.v[2] = (args_info.qos_arg) & 0xff;
|
||||
options.qos.v[1] = ((args_info.qos_arg) >> 8) & 0xff;
|
||||
options.qos.v[0] = ((args_info.qos_arg) >> 16) & 0xff;
|
||||
options.qos.l = 4;
|
||||
options.qos.v[3] = (args_info.qos_arg) & 0xff;
|
||||
options.qos.v[2] = ((args_info.qos_arg) >> 8)& 0xff;
|
||||
options.qos.v[1] = ((args_info.qos_arg) >> 16) & 0xff;
|
||||
options.qos.v[0] = ((args_info.qos_arg) >> 24) & 0xff;
|
||||
/* Extensions according to 3GPP TS 24.008 */
|
||||
if (args_info.qose1_given == 1 ) {
|
||||
options.qos.l = 12;
|
||||
options.qos.v[11] = (args_info.qose1_arg) & 0xff;
|
||||
options.qos.v[10] = ((args_info.qose1_arg) >> 8)& 0xff;
|
||||
options.qos.v[9] = ((args_info.qose1_arg) >> 16)& 0xff;
|
||||
options.qos.v[8] = ((args_info.qose1_arg) >> 24)& 0xff;
|
||||
options.qos.v[7] = ((args_info.qose1_arg) >> 32)& 0xff;
|
||||
options.qos.v[6] = ((args_info.qose1_arg) >> 40) & 0xff;
|
||||
options.qos.v[5] = ((args_info.qose1_arg) >> 48) & 0xff;
|
||||
options.qos.v[4] = ((args_info.qose1_arg) >> 56) & 0xff;
|
||||
if (args_info.qose2_given == 1 ) {
|
||||
options.qos.l = 13;
|
||||
options.qos.v[12] = (args_info.qose2_arg) & 0xff;
|
||||
if (args_info.qose3_given == 1 ) {
|
||||
options.qos.l = 15;
|
||||
options.qos.v[14] = (args_info.qose3_arg) & 0xff;
|
||||
options.qos.v[13] = ((args_info.qose3_arg) >> 8)& 0xff;
|
||||
if (args_info.qose4_given == 1 ) {
|
||||
options.qos.l = 17;
|
||||
options.qos.v[16] = (args_info.qose4_arg) & 0xff;
|
||||
options.qos.v[15] = ((args_info.qose4_arg) >> 8)& 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* charging */
|
||||
options.cch = args_info.charging_arg;
|
||||
|
@ -1316,18 +1351,18 @@ int main(int argc, char **argv)
|
|||
pdp->ipif = tun; /* TODO */
|
||||
iparr[n].pdp = pdp;
|
||||
|
||||
if (options.qos.l > sizeof(pdp->qos_req0)) {
|
||||
if (options.gtpversion == 0) {
|
||||
if (options.qos.l - 1 > sizeof(pdp->qos_req0)) {
|
||||
sys_err(LOG_ERR, __FILE__, __LINE__, 0, "QoS length too big");
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
memcpy(pdp->qos_req0, options.qos.v, options.qos.l);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
pdp->qos_req.l = 4;
|
||||
pdp->qos_req.v[0] = 0x00;
|
||||
memcpy(pdp->qos_req.v+1, options.qos.v, options.qos.l);
|
||||
pdp->qos_req.l = options.qos.l ;
|
||||
memcpy(pdp->qos_req.v, options.qos.v, options.qos.l);
|
||||
|
||||
pdp->selmode = options.selmode;
|
||||
|
||||
|
|
Reference in New Issue