#include #include #include #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include static void print_usage(const char *prog_name) { printf("Usage: %s [-h] [--features FOO,BAR,BAZ] dst_host site_id [trx_num]\n", prog_name); } static void print_help(const char *prog_name) { print_usage(prog_name); printf(" -h --help This text.\n"); printf(" -f --features FOO,BAR,BAZ BTS features to issue on OML startup.\n" " The names correspond to BTS_FEAT_* constants\n" " as defined in osmocom/gsm/bts_features.h,\n" " e.g. '-f VAMOS'\n"); } struct { char *dst_host; int site_id; int trx_num; char *features; } cmdline = { .trx_num = 8, }; void parse_cmdline(int argc, char **argv) { while (1) { int option_index = 0, c; static struct option long_options[] = { {"help", 0, 0, 'h'}, {"features", 1, 0, 'f'}, { "debug", 1, 0, 'd' }, { "disable-color", 0, 0, 's' }, { "timestamp", 0, 0, 'T' }, { "log-level", 1, 0, 'e' }, {0} }; c = getopt_long(argc, argv, "hf:d:sTe:", long_options, &option_index); if (c == -1) break; switch (c) { case 'h': print_help(argv[0]); exit(0); case 'f': cmdline.features = optarg; break; case 's': log_set_use_color(osmo_stderr_target, 0); break; case 'd': log_parse_category_mask(osmo_stderr_target, optarg); break; case 'T': log_set_print_timestamp(osmo_stderr_target, 1); break; case 'e': log_set_log_level(osmo_stderr_target, atoi(optarg)); break; default: /* catch unknown options *as well as* missing arguments. */ fprintf(stderr, "Error in command line options. Exiting.\n"); exit(-1); } } if (optind + 2 > argc) { print_usage(argv[0]); exit(1); } cmdline.dst_host = argv[optind]; cmdline.site_id = atoi(argv[optind + 1]); if (optind + 2 < argc) cmdline.trx_num = atoi(argv[optind + 2]); if (optind + 3 < argc) { print_usage(argv[0]); exit(1); } } void set_bts_features(struct bitvec *features, char *features_str) { char *saveptr = NULL; char *token; if (!features_str) return; while ((token = strtok_r(features_str, ",", &saveptr))) { enum osmo_bts_features feat; features_str = NULL; feat = get_string_value(osmo_bts_features_names, token); if ((int)feat < 0) { fprintf(stderr, "Unknown BTS feature: '%s'\n", token); exit(-1); } osmo_bts_set_feature(features, feat); } } int main(int argc, char **argv) { struct gsm_bts *bts; struct gsm_bts_trx *trx; struct bsc_oml_host *bsc_oml_host; int i; tall_bts_ctx = talloc_named_const(NULL, 1, "OsmoBTS context"); msgb_talloc_ctx_init(tall_bts_ctx, 10*1024); osmo_init_logging2(tall_bts_ctx, &bts_log_info); log_set_print_category(osmo_stderr_target, 1); log_set_print_category_hex(osmo_stderr_target, 0); parse_cmdline(argc, argv); g_bts_sm = gsm_bts_sm_alloc(tall_bts_ctx); if (!g_bts_sm) exit(1); bts = gsm_bts_alloc(g_bts_sm, 0); if (!bts) exit(1); bts->ip_access.site_id = cmdline.site_id; bts->ip_access.bts_id = 0; /* Additional TRXs */ for (i = 1; i < cmdline.trx_num; i++) { trx = gsm_bts_trx_alloc(bts); if (!trx) exit(1); } if (bts_init(bts) < 0) exit(1); set_bts_features(bts->features, cmdline.features); /* VAMOS: allocate shadow timeslots for each TRX */ if (osmo_bts_has_feature(bts->features, BTS_FEAT_VAMOS)) { llist_for_each_entry(trx, &bts->trx_list, list) gsm_bts_trx_init_shadow_ts(trx); } //btsb = bts_role_bts(bts); abis_init(bts); bsc_oml_host = talloc_zero(bts, struct bsc_oml_host); OSMO_ASSERT(bsc_oml_host); bsc_oml_host->addr = talloc_strdup(bsc_oml_host, cmdline.dst_host); OSMO_ASSERT(bsc_oml_host->addr); llist_add_tail(&bsc_oml_host->list, &bts->bsc_oml_hosts); if (abis_open(bts, "OMLdummy") != 0) exit(1); while (1) { osmo_select_main(0); } return EXIT_SUCCESS; }