abisip-find: add -l to list base stations instead of streaming replies
To get an overview of what base stations are present in a network, particularly with many base stations being present, it is particularly useful to get a list of connected base stations instead of just output of received replies. Keep a sorted list of known base stations, which time out after 10 seconds. Print additions and removals, and total amount of replies received. On each change, print the entire list. Output a running total of replies received, to provide comfort to the reader that something is still happening, and to confirm that the shown listing is still up-to-date (updated on the same line by means of '\r'). It looks like: ----- Mon Dec 25 18:59:43 2017 0: MAC_Address='00:02:95:07:dc:bd' IP_Address='192.168.0.124' Unit_ID='1/1/1' Location_1='Unknown' Location_2='3GAP' Equipment_Version='237B015_C' Software_Version='unknown' Unit_Name='Unknown' Serial_Number='000295-0000152614' 1: MAC_Address='00:02:95:07:dd:57' IP_Address='192.168.0.15' Unit_ID='1/1/1' Location_1='Unknown' Location_2='3GAP' Equipment_Version='237B015_C' Software_Version='unknown' Unit_Name='Unknown' Serial_Number='000295-0000154153' Total: 2 RX: 11 ----- Mon Dec 25 19:00:12 2017 LOST: MAC_Address='00:02:95:07:dd:57' IP_Address='192.168.0.15' Unit_ID='1/1/1' Location_1='Unknown' Location_2='3GAP' Equipment_Version='237B015_C' Software_Version='unknown' Unit_Name='Unknown' Serial_Number='000295-0000154153' ----- Mon Dec 25 19:00:12 2017 0: MAC_Address='00:02:95:07:dc:bd' IP_Address='192.168.0.124' Unit_ID='1/1/1' Location_1='Unknown' Location_2='3GAP' Equipment_Version='237B015_C' Software_Version='unknown' Unit_Name='Unknown' Serial_Number='000295-0000152614' Total: 1 RX: 15 ----- Mon Dec 25 19:00:28 2017 New: MAC_Address='00:02:95:07:dd:57' IP_Address='192.168.0.15' Unit_ID='1/1/1' Location_1='Unknown' Location_2='3GAP' Equipment_Version='237B015_C' Software_Version='unknown' Unit_Name='Unknown' Serial_Number='000295-0000154153' ----- Mon Dec 25 19:00:28 2017 0: MAC_Address='00:02:95:07:dc:bd' IP_Address='192.168.0.124' Unit_ID='1/1/1' Location_1='Unknown' Location_2='3GAP' Equipment_Version='237B015_C' Software_Version='unknown' Unit_Name='Unknown' Serial_Number='000295-0000152614' 1: MAC_Address='00:02:95:07:dd:57' IP_Address='192.168.0.15' Unit_ID='1/1/1' Location_1='Unknown' Location_2='3GAP' Equipment_Version='237B015_C' Software_Version='unknown' Unit_Name='Unknown' Serial_Number='000295-0000154153' RX: 18 Change-Id: I4201876431029b303dbd10e46492228379c9782a
This commit is contained in:
parent
2a9ac19863
commit
5bf1e15c55
|
@ -25,17 +25,22 @@
|
|||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <getopt.h>
|
||||
#include <time.h>
|
||||
#include <talloc.h>
|
||||
|
||||
#include <osmocom/core/select.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/gsm/protocol/ipaccess.h>
|
||||
#include <osmocom/gsm/ipa.h>
|
||||
#include <osmocom/bsc/gsm_data.h>
|
||||
|
||||
static struct {
|
||||
const char *ifname;
|
||||
bool list_view;
|
||||
} cmdline_opts = {
|
||||
.ifname = NULL,
|
||||
.list_view = false,
|
||||
};
|
||||
|
||||
static void print_help()
|
||||
|
@ -44,6 +49,9 @@ static void print_help()
|
|||
printf("Usage: abisip-find [-l] [<interface-name>]\n");
|
||||
printf(" <interface-name> Specify the outgoing network interface,\n"
|
||||
" e.g. 'eth0'\n");
|
||||
printf(" -l --list-view Instead of printing received responses,\n"
|
||||
" output a sorted list of currently present\n"
|
||||
" base stations and change events.\n");
|
||||
}
|
||||
|
||||
static void handle_options(int argc, char **argv)
|
||||
|
@ -52,10 +60,11 @@ static void handle_options(int argc, char **argv)
|
|||
int option_index = 0, c;
|
||||
static struct option long_options[] = {
|
||||
{"help", 0, 0, 'h'},
|
||||
{"list-view", 0, 0, 'l'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long(argc, argv, "h",
|
||||
c = getopt_long(argc, argv, "hl",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
@ -64,6 +73,9 @@ static void handle_options(int argc, char **argv)
|
|||
case 'h':
|
||||
print_help();
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'l':
|
||||
cmdline_opts.list_view = true;
|
||||
break;
|
||||
default:
|
||||
/* catch unknown options *as well as* missing arguments. */
|
||||
fprintf(stderr, "Error in command line options. Exiting. Try --help.\n");
|
||||
|
@ -159,22 +171,137 @@ static int bcast_find(int fd)
|
|||
return sendto(fd, find_pkt, sizeof(find_pkt), 0, (struct sockaddr *) &sa, sizeof(sa));
|
||||
}
|
||||
|
||||
static int parse_response(unsigned char *buf, int len)
|
||||
static char *parse_response(void *ctx, unsigned char *buf, int len)
|
||||
{
|
||||
uint8_t t_len;
|
||||
uint8_t t_tag;
|
||||
uint8_t *cur = buf;
|
||||
char *out = talloc_zero_size(ctx, 512);
|
||||
|
||||
while (cur < buf + len) {
|
||||
t_len = *cur++;
|
||||
t_tag = *cur++;
|
||||
|
||||
printf("%s='%s' ", ipa_ccm_idtag_name(t_tag), cur);
|
||||
out = talloc_asprintf_append(out, "%s='%s' ", ipa_ccm_idtag_name(t_tag), cur);
|
||||
|
||||
cur += t_len;
|
||||
}
|
||||
printf("\n");
|
||||
return 0;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
struct base_station {
|
||||
struct llist_head entry;
|
||||
char *line;
|
||||
time_t timestamp;
|
||||
};
|
||||
|
||||
LLIST_HEAD(base_stations);
|
||||
|
||||
void *ctx = NULL;
|
||||
|
||||
void print_timestamp()
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
printf("\n\n----- %s\n", ctime(&now));
|
||||
}
|
||||
|
||||
struct base_station *base_station_parse(unsigned char *buf, int len)
|
||||
{
|
||||
struct base_station *new_bs = talloc_zero(ctx, struct base_station);
|
||||
new_bs->line = parse_response(new_bs, buf, len);
|
||||
new_bs->timestamp = time(NULL);
|
||||
return new_bs;
|
||||
}
|
||||
|
||||
bool base_stations_add(struct base_station *new_bs)
|
||||
{
|
||||
struct base_station *bs;
|
||||
|
||||
llist_for_each_entry(bs, &base_stations, entry) {
|
||||
int c = strcmp(new_bs->line, bs->line);
|
||||
if (!c) {
|
||||
/* entry already exists. */
|
||||
bs->timestamp = new_bs->timestamp;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (c < 0) {
|
||||
/* found the place to add the entry */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
print_timestamp();
|
||||
printf("New:\n%s\n", new_bs->line);
|
||||
|
||||
llist_add_tail(&new_bs->entry, &bs->entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool base_stations_timeout()
|
||||
{
|
||||
struct base_station *bs, *next_bs;
|
||||
time_t now = time(NULL);
|
||||
bool changed = false;
|
||||
|
||||
llist_for_each_entry_safe(bs, next_bs, &base_stations, entry) {
|
||||
if (now - bs->timestamp < 10)
|
||||
continue;
|
||||
print_timestamp();
|
||||
printf("LOST:\n%s\n", bs->line);
|
||||
|
||||
llist_del(&bs->entry);
|
||||
talloc_free(bs);
|
||||
changed = true;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
void base_stations_print()
|
||||
{
|
||||
struct base_station *bs;
|
||||
int count = 0;
|
||||
|
||||
print_timestamp();
|
||||
llist_for_each_entry(bs, &base_stations, entry) {
|
||||
printf("%3d: %s\n", count, bs->line);
|
||||
count++;
|
||||
}
|
||||
printf("\nTotal: %d\n", count);
|
||||
}
|
||||
|
||||
static void base_stations_bump(bool known_changed)
|
||||
{
|
||||
bool changed = known_changed;
|
||||
if (base_stations_timeout())
|
||||
changed = true;
|
||||
|
||||
if (changed)
|
||||
base_stations_print();
|
||||
}
|
||||
|
||||
static void handle_response(unsigned char *buf, int len)
|
||||
{
|
||||
static unsigned int responses = 0;
|
||||
responses++;
|
||||
|
||||
if (cmdline_opts.list_view) {
|
||||
bool changed = false;
|
||||
struct base_station *bs = base_station_parse(buf, len);
|
||||
if (base_stations_add(bs))
|
||||
changed = true;
|
||||
else
|
||||
talloc_free(bs);
|
||||
base_stations_bump(changed);
|
||||
printf("RX: %u \r", responses);
|
||||
fflush(stdout);
|
||||
} else {
|
||||
char *line = parse_response(ctx, buf, len);
|
||||
printf(line);
|
||||
printf("\n");
|
||||
talloc_free(line);
|
||||
}
|
||||
}
|
||||
|
||||
static int read_response(int fd)
|
||||
|
@ -195,7 +322,8 @@ static int read_response(int fd)
|
|||
if (buf[4] != IPAC_MSGT_ID_RESP)
|
||||
return 0;
|
||||
|
||||
return parse_response(buf+6, len-6);
|
||||
handle_response(buf+6, len-6);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bfd_cb(struct osmo_fd *bfd, unsigned int flags)
|
||||
|
@ -217,6 +345,8 @@ static void timer_cb(void *_data)
|
|||
|
||||
bfd->when |= BSC_FD_WRITE;
|
||||
|
||||
base_stations_bump(false);
|
||||
|
||||
osmo_timer_schedule(&timer, 5, 0);
|
||||
}
|
||||
|
||||
|
@ -231,8 +361,10 @@ int main(int argc, char **argv)
|
|||
handle_options(argc, argv);
|
||||
|
||||
if (!cmdline_opts.ifname)
|
||||
fprintf(stdout, "you might need to specify the outgoing\n"
|
||||
" network interface, e.g. ``%s eth0''\n", argv[0]);
|
||||
fprintf(stdout, "- You might need to specify the outgoing\n"
|
||||
" network interface, e.g. ``%s eth0''\n", argv[0]);
|
||||
if (!cmdline_opts.list_view)
|
||||
fprintf(stdout, "- You may find the --list-view option convenient.\n");
|
||||
|
||||
bfd.cb = bfd_cb;
|
||||
bfd.when = BSC_FD_READ | BSC_FD_WRITE;
|
||||
|
|
Loading…
Reference in New Issue