1 /*
2  * Copyright 2018 Oticon A/S
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include <stdlib.h>
7 #include <string.h>
8 #include "bs_burstint_args.h"
9 #include "bs_tracing.h"
10 #include "bs_oswrap.h"
11 #include "bs_utils.h"
12 #include "bs_pc_2G4_utils.h"
13 
14 char executable_name[] = "bs_device_2G4_burst_interf";
component_print_post_help()15 void component_print_post_help(){
16   fprintf(stdout,
17           "Generate bursts of interference of a given <type> centered in a\n"
18           "given <centerf> lasting from <timestart> to <timeend>\n\n");
19 }
20 
21 burstint_args_t *args_g;
22 
cmd_trace_lvl_found(char * argv,int offset)23 static void cmd_trace_lvl_found(char * argv, int offset){
24   bs_trace_set_level(args_g->verb);
25 }
26 
cmd_gdev_nbr_found(char * argv,int offset)27 static void cmd_gdev_nbr_found(char * argv, int offset){
28   bs_trace_set_prefix_dev(args_g->global_device_nbr);
29 }
30 
31 static double power_value;
32 static double center_freq;
33 static char *type_argv;
34 
cmd_powervalue_found(char * argv,int offset)35 static void cmd_powervalue_found(char * argv, int offset){
36   args_g->powerdBm = p2G4_power_from_d(power_value);
37 }
38 
cmd_center_freq_found(char * argv,int offset)39 static void cmd_center_freq_found(char * argv, int offset){
40   int error = p2G4_freq_from_d(center_freq, 0, &args_g->center_freq);
41   if (error) {
42     bs_trace_error_line("Could not parse center frequency %s\n", argv);
43   }
44   bs_trace_raw(9,"center frequency set to %.2lfMHz (+2400)\n",
45                ((double)args_g->center_freq)/(1<<P2G4_freq_FRACB));
46 }
47 
cmd_type_found(char * argv,int offset)48 static void cmd_type_found(char * argv, int offset){
49   int error = p2G4_modulation_from_string(type_argv, &args_g->type,
50                                           OnlyNonReceivable, 1);
51   if ( error != 0 ) {
52     bs_trace_error_line("Could not interpret modulation type %s\n",type_argv);
53   }
54 }
55 
56 /**
57  * Check the arguments provided in the command line: set args based on it
58  * or defaults, and check they are correct
59  */
bs_burstint_argsparse(int argc,char * argv[],burstint_args_t * args)60 void bs_burstint_argsparse(int argc, char *argv[], burstint_args_t *args)
61 {
62   int i;
63 
64   args_g = args;
65   bs_args_struct_t args_struct[] = {
66       BS_BASIC_DEVICE_2G4_TYPICAL_OPTIONS_ARG_STRUCT,
67       { false, false , false, "power",       "powerdBm", 'f', (void*)&power_value, cmd_powervalue_found,  "In dBm power of the interference (20dBm)"},
68       { false, true  , false, "centerfreq",  "centerf",  'f', (void*)&center_freq, cmd_center_freq_found, "center_freq in MHz"},
69       { false, false , false, "type",      "modu_type",  's', (void*)&type_argv,   cmd_type_found,        "{CW,(WLAN),BLE,WN{1|2|4|8|16|20|40|80}} Type of interference (default CW)"},
70       { true , false , false, "timestart",      "time",  'l',  NULL,               NULL,            "Times at which the interference burst shall start (omit to run from the begining) (up to " STR(BS_BUSRTINT_MAX_TIMES) " bursts)"},
71       { true , false , false, "timeend"  ,      "time",  'l',  NULL,               NULL,            "Times at which the interference burst shall end (omit the last to run until the end of the simulation) (up to " STR(BS_BUSRTINT_MAX_TIMES) " burst)"},
72       ARG_TABLE_ENDMARKER
73   };
74 
75   bs_args_typical_dev_set_defaults((bs_basic_dev_args_t *)args, args_struct);
76   args->n_times_start = 0;
77   args->n_times_end   = 0;
78   args->type          = P2G4_MOD_CWINTER;
79   args->center_freq   = P2G4_INVALID_FREQ;
80   args->powerdBm = p2G4_power_from_d(20);
81   static char default_phy[] ="2G4";
82 
83   for (i=1; i<argc; i++) {
84     int offset;
85     double time;
86     if ( !bs_args_parse_one_arg(argv[i], args_struct) ){
87       if ( ( offset = bs_is_option(argv[i], "timestart", 0) ) ) {
88         while ( ( i + 1 < argc ) && ( argv[i+1][0] != '-' ) ) {
89           i += 1;
90           if ( sscanf(argv[i],"%lf",&time) != 1 ){
91             bs_trace_error_line("Could not parse timestart entry nbr %i (%s)\n",
92                                 args->n_times_start+1, argv[i]);
93           }
94           args->times_start[args->n_times_start] = time;
95           bs_trace_raw(9,"added timestart[%i] = %"PRItime" to list\n",
96                        args->n_times_start,
97                        args->times_start[args->n_times_start]);
98           args->n_times_start += 1;
99         }
100       }
101       else if ( ( offset = bs_is_option(argv[i], "timeend", 0) ) ) {
102         while ( ( i + 1 < argc ) && ( argv[i+1][0] != '-' ) ) {
103           i += 1;
104           if ( sscanf(argv[i],"%lf",&time) != 1 ){
105             bs_trace_error_line("Could not parse timeend entry nbr %i (%s)\n",
106                                 args->n_times_end+1, argv[i]);
107           }
108           args->times_end[args->n_times_end] = time;
109           bs_trace_raw(9,"added timeend[%i] = %"PRItime" to list\n",
110                        args->n_times_end, args->times_end[args->n_times_end]);
111           args->n_times_end += 1;
112         }
113       }
114       else {
115         bs_args_print_switches_help(args_struct);
116         bs_trace_error_line("Unknown command line switch '%s'\n",argv[i]);
117       }
118     }
119   }
120 
121   bs_args_typical_dev_post_check((bs_basic_dev_args_t *)args, args_struct, default_phy);
122   if ( args->center_freq == P2G4_INVALID_FREQ ) {
123     bs_args_print_switches_help(args_struct);
124     bs_trace_error_line("The center frequency needs to be specified\n");
125   }
126 
127   if ( args->n_times_start == 0 ){
128     args->n_times_start = 1;
129     args->times_start[0] = 1;
130   }
131   if ( args->n_times_end == args->n_times_start - 1 ){
132     args->n_times_end = args->n_times_start ;
133     args->times_end[args->n_times_end-1] = TIME_NEVER;
134   }
135   if ( args->n_times_end != args->n_times_start ){
136     bs_trace_error_line("You need to provide the same number of end and start "
137                         "times (or one less if you want to let the last burst "
138                         "run forever) (run with --help for more info)\n");
139   }
140 }
141