diff --git a/src/telnet_interface.c b/src/telnet_interface.c index b0a8e4334..68755481d 100644 --- a/src/telnet_interface.c +++ b/src/telnet_interface.c @@ -26,9 +26,17 @@ #include #include +#include extern void telnet_parse(struct telnet_connection *connection, char *line); +#define WRITE_CONNECTION(fd, msg...) \ + int ret; \ + char buf[4096]; \ + snprintf(buf, sizeof(buf), msg); \ + ret = write(fd, buf, strlen(buf)); + + /* per connection data */ LLIST_HEAD(active_connections); @@ -82,6 +90,7 @@ void telnet_write_help(int fd) { "call IMSI (number)\n" "get_channel IMSI Add use count on an active channel\n" "put_channel IMSI Remove use count on an active channel\n" + "show This will show the channel allocation\n" "48 IMSI 0xAB 0xEF...Send GSM 04.08\n" "11 IMSI 0xAB 0xEF...Send GSM 04.11\n"; @@ -148,6 +157,58 @@ void telnet_send_gsm_11(struct telnet_connection *connection) { printf("sending gsm04.11 message\n"); } +static void show_bts(int fd, struct gsm_bts *bts) { + WRITE_CONNECTION(fd, + "BTS #%u on link %u LOC: %u TRX: %d CCCH0: arfcn:%u,#%u\n", + bts->nr, bts->bts_nr, bts->location_area_code, + bts->num_trx, bts->c0->arfcn, bts->c0->nr) +} + +static void show_trx(int fd, struct gsm_bts_trx *trx) { + WRITE_CONNECTION(fd, + " TRX: %u ARFCN: %u\n", + trx->nr, trx->arfcn) +} + +static void show_ts(int fd, struct gsm_bts_trx_ts *ts) { + WRITE_CONNECTION(fd, + " TS: #%u pchan: %d flags: %u\n", + ts->nr, ts->pchan, ts->flags); +} + +static void show_lchan(int fd, struct gsm_lchan *lchan) { + struct gsm_subscriber *subscr = lchan->subscr; + WRITE_CONNECTION(fd, + " LCHAN: #%u type: %d subscriber: %s/%s/%s use: %d loc: %p\n", + lchan->nr, lchan->type, + subscr ? subscr->imsi : "na", + subscr ? subscr->tmsi : "na", + subscr ? subscr->name : "na", + lchan->use_count, lchan->loc_operation); +} + +void telnet_list_channels(struct telnet_connection *connection) { + int bts_no, trx, lchan_no, ts_no; + struct gsm_network *network = connection->network; + + for (bts_no = 0; bts_no < network->num_bts; ++bts_no) { + struct gsm_bts *bts = &network->bts[bts_no]; + show_bts(connection->fd.fd, bts); + + for (trx = 0; trx < bts->num_trx; ++trx) { + show_trx(connection->fd.fd, &bts->trx[trx]); + for (ts_no = 0; ts_no < 8; ++ts_no) { + show_ts(connection->fd.fd, &bts->trx[trx].ts[ts_no]); + for (lchan_no = 0; lchan_no < TS_MAX_LCHAN; ++lchan_no) { + struct gsm_lchan *lchan = + &bts->trx[trx].ts[ts_no].lchan[lchan_no]; + show_lchan(connection->fd.fd, lchan); + } + } + } + } +} + static int client_data(struct bsc_fd *fd, unsigned int what) { char buf[4096]; int ret; diff --git a/src/telnet_parser.l b/src/telnet_parser.l index 3af0d5818..796c5c915 100644 --- a/src/telnet_parser.l +++ b/src/telnet_parser.l @@ -41,12 +41,14 @@ extern void telnet_put_channel(struct telnet_connection*, const char *imsi); extern void telnet_get_channel(struct telnet_connection*, const char *imsi); extern void telnet_send_gsm_48(struct telnet_connection*); extern void telnet_send_gsm_11(struct telnet_connection*); +extern void telnet_list_channels(struct telnet_connection*); static const int PAGE_LEN = 5; /* "page " */ static const int CALL_LEN = 5; /* "call " */ static const int PUT_LEN = 12; /* "put_channel " */ static const int GET_LEN = 12; /* "get_channel " */ static const int NET_LEN = 3; /* "48 " "11 " */ +static const int SHOW_LEN = 5; /* "show " */ #define YY_EXTRA_TYPE struct telnet_connection* @@ -77,6 +79,7 @@ CMD_PUT_CHANNEL "put_channel" CMD_CALL "call" CMD_48 "48" CMD_11 "11" +CMD_SHOW "show" LINE_END \n|\r\n HEX [0][x][0-9a-zA-Z][0-9a-zA-Z] @@ -87,6 +90,7 @@ HEX [0][x][0-9a-zA-Z][0-9a-zA-Z] {CMD_HELP}{LINE_END} {telnet_write_help(yyextra->fd.fd); yyterminate();} {CMD_EXIT}{LINE_END} {telnet_close_client(&yyextra->fd); yyterminate();} {CMD_CLOSE}{LINE_END} {telnet_close_client(&yyextra->fd); yyterminate();} +{CMD_SHOW}{LINE_END} {telnet_list_channels(yyextra); yyterminate();} {CMD_PAGE}[ ][0-9]+{LINE_END} { PREPARE_STRING(PAGE_LEN) telnet_page(yyextra, str, 0);