diff options
author | Harald Welte <laforge@gnumonks.org> | 2009-03-10 12:21:45 +0000 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2009-03-10 12:21:45 +0000 |
commit | 404cdd8951647b0f9ae9021cbc04798a05282a23 (patch) | |
tree | a7d3cd93fd57961d0487f3ec631f2951334d4086 | |
parent | 68628e8479519ab49066b5b19f35a68884c6bab5 (diff) |
make telnet interface use VTY code
-rw-r--r-- | include/openbsc/telnet_interface.h | 4 | ||||
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/telnet_interface.c | 228 | ||||
-rw-r--r-- | src/telnet_parser.l | 190 |
4 files changed, 21 insertions, 407 deletions
diff --git a/include/openbsc/telnet_interface.h b/include/openbsc/telnet_interface.h index 228b6231f..b5a0ec400 100644 --- a/include/openbsc/telnet_interface.h +++ b/include/openbsc/telnet_interface.h @@ -25,6 +25,8 @@ #include "linuxlist.h" #include "select.h" +#include <vty/vty.h> + #define TELNET_COMMAND_48 1 #define TELNET_COMMAND_11 2 @@ -32,6 +34,8 @@ struct telnet_connection { struct llist_head entry; struct gsm_network *network; struct bsc_fd fd; + struct vty *vty; + int bts; int command; diff --git a/src/Makefile.am b/src/Makefile.am index 3847af36b..b9e942788 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,14 +6,14 @@ noinst_LIBRARIES = libbsc.a libvty.a libbsc_a_SOURCES = abis_rsl.c abis_nm.c gsm_04_08.c gsm_data.c \ gsm_subscriber.c msgb.c select.c chan_alloc.c timer.c debug.c db.c \ - gsm_04_11.c telnet_interface.c telnet_parser.l subchan_demux.c \ + gsm_04_11.c telnet_interface.c subchan_demux.c \ trau_frame.c trau_mux.c paging.c e1_config.c e1_input.c tlv_parser.c \ input/misdn.c input/ipaccess.c signal.c gsm_utils.c libvty_a_SOURCES = vty/buffer.c vty/command.c vty/vector.c vty/vty.c -bsc_hack_SOURCES = bsc_hack.c -bsc_hack_LDADD = libbsc.a -ldl -ldbi +bsc_hack_SOURCES = bsc_hack.c vty_interface.c +bsc_hack_LDADD = libbsc.a libvty.a -ldl -ldbi -lcrypt bs11_config_SOURCES = bs11_config.c abis_nm.c gsm_data.c msgb.c debug.c select.c timer.c rs232.c tlv_parser.c diff --git a/src/telnet_interface.c b/src/telnet_interface.c index 3d3ed7663..422af3b22 100644 --- a/src/telnet_interface.c +++ b/src/telnet_interface.c @@ -35,8 +35,6 @@ #include <openbsc/paging.h> #include <openbsc/signal.h> -extern void telnet_parse(struct telnet_connection *connection, char *line); - #define WRITE_CONNECTION(fd, msg...) \ int ret; \ char buf[4096]; \ @@ -64,6 +62,8 @@ void telnet_init(struct gsm_network *network, int port) { struct sockaddr_in sock_addr; int fd, on = 1; + bsc_vty_init(network); + fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (fd < 0) { @@ -93,26 +93,10 @@ void telnet_init(struct gsm_network *network, int port) { bsc_register_fd(&server_socket); /* register callbacks */ +#if 0 register_signal_handler(SS_PAGING, telnet_paging_callback, network); register_signal_handler(SS_SMS, telnet_sms_callback, network); -} - -void telnet_write_help(int fd) { - int ret; - static char *msg = - "Help for the ad-hoc telnet command line interface\n" - "The generic pattern is CMD LEN DATA\\n or just CMD\n" - "where CMD is one of the following:\n" - "help\n" - "page IMSI (type)\n" - "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. proto and msg byte then data\n" - "11 IMSI 0xAB 0xEF...Send GSM 04.11\n"; - - ret = write(fd, msg, strlen(msg)); +#endif } static void print_welcome(int fd) { @@ -142,200 +126,10 @@ int telnet_close_client(struct bsc_fd *fd) { return 0; } -void telnet_error_client(int fd) { - int ret; - static char *msg = "Something went wrong. Please try again.\n"; - - printf("Error\n"); - ret = write(fd, msg, strlen(msg)); -} - -static struct gsm_lchan* find_channel(struct gsm_bts *bts, const char *imsi, - const char **error, int fd) { - int ret; - struct gsm_lchan *lchan; - struct gsm_subscriber *subscr; - - subscr = subscr_get_by_imsi(imsi); - if (!subscr) { - ret = write(fd, error[0], strlen(error[0])); - return NULL; - } - - lchan = lchan_find(bts, subscr); - if (!lchan) - ret = write(fd, error[1], strlen(error[1])); - - subscr_put(subscr); - return lchan; -} - -void telnet_page(struct telnet_connection *connection, const char *imsi, int type) { - int ret; - static const char* error[] = { - "paging: IMSI not found\n", - "paging: No channel allocated for IMSI -> will allocate\n" }; - struct gsm_bts *bts = &connection->network->bts[connection->bts]; - struct gsm_lchan *lchan = find_channel(bts, imsi, error, connection->fd.fd); - - if (lchan) { - static const char *msg = "paging: A Channel is already allocated.\n"; - ret = write(connection->fd.fd, msg, strlen(msg)); - return; - } - - struct gsm_subscriber *subscr = subscr_get_by_imsi(imsi); - if (!subscr) - return; - - paging_request(bts, subscr, type, NULL, NULL); -} - -void telnet_put_channel(struct telnet_connection *connection, const char *imsi) { - static const char* error[] = { - "put_channel: IMSI not found\n", - "put_channel: No channel allocated for IMSI\n" }; - struct gsm_bts *bts = &connection->network->bts[connection->bts]; - struct gsm_lchan *lchan = find_channel(bts, imsi, error, connection->fd.fd); - - if (!lchan) - return; - - put_lchan(lchan); -} - -void telnet_get_channel(struct telnet_connection *connection, const char *imsi) { - static const char* error[] = { - "get_channel: IMSI not found\n", - "get_channel: No channel allocated for IMSI\n" }; - struct gsm_bts *bts = &connection->network->bts[connection->bts]; - struct gsm_lchan *lchan = find_channel(bts, imsi, error, connection->fd.fd); - - if (!lchan) - return; - - use_lchan(lchan); -} - -void telnet_call(struct telnet_connection *connection, const char* imsi, - const char *origin) { - static const char* error[] = { - "call: IMSI not found\n", - "call: No channel allocated for IMSI\n" }; - struct gsm_bts *bts = &connection->network->bts[connection->bts]; - struct gsm_lchan *lchan = find_channel(bts, imsi, error, connection->fd.fd); - - if (!lchan) - return; - - /* TODO: add the origin */ - gsm48_cc_tx_setup(lchan, NULL); -} - -void telnet_send_gsm_48(struct telnet_connection *connection) { - static const char* error[] = { - "48: IMSI not found\n", - "48: No channel allocated for IMSI\n" }; - int ret; - struct gsm_bts *bts = &connection->network->bts[connection->bts]; - struct gsm_lchan *lchan = find_channel(bts, connection->imsi, error, connection->fd.fd); - - if (!lchan) - return; - - if (connection->read < 2) { - static const char *msg = "48: Need at least two bytes"; - ret = write(connection->fd.fd, msg, strlen(msg)); - return; - } - - struct msgb *msg = gsm48_msgb_alloc(); - struct gsm48_hdr *gh; - int i; - - gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + connection->read-2); - msg->lchan = lchan; - - gh->proto_discr = connection->commands[0]; - gh->msg_type = connection->commands[1]; - for (i = 2; i < connection->read; ++i) - gh->data[i-2] = connection->commands[i]; - - gsm48_sendmsg(msg); -} - -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: %12s flags: %u\n", - ts->nr, gsm_pchan_name(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: %7s count: %d subscriber: %s/%s/%s use: %d loc: %p\n", - lchan->nr, gsm_lchan_name(lchan->type), - lchan->use_count, - 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; - - ret = read(fd->fd, buf, sizeof(buf)-1); - buf[ret] = '\0'; - - /* connection is gone */ - if (ret <= 0) - return telnet_close_client(fd); - - /* time to parse. This code assumes that the input is line based */ - telnet_parse((struct telnet_connection*)fd->data, buf); - - return 0; +static int client_data(struct bsc_fd *fd, unsigned int what) +{ + struct telnet_connection *conn = fd->data; + return vty_read(conn->vty); } static int telnet_new_connection(struct bsc_fd *fd, unsigned int what) { @@ -363,9 +157,14 @@ static int telnet_new_connection(struct bsc_fd *fd, unsigned int what) { print_welcome(new_connection); + connection->vty = vty_create(new_connection); + if (!connection->vty) + return -1; + return 0; } +#if 0 static int telnet_paging_callback(unsigned int subsys, unsigned int singal, void *handler_data, void *signal_data) { @@ -399,3 +198,4 @@ static int telnet_sms_callback(unsigned int subsys, unsigned int signal, return 0; } +#endif diff --git a/src/telnet_parser.l b/src/telnet_parser.l deleted file mode 100644 index e4327191d..000000000 --- a/src/telnet_parser.l +++ /dev/null @@ -1,190 +0,0 @@ -/* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org> - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ -/* - * I'm lazy and will not introduce lemon to this game. Our telnet - * interface is matching line based so we can have a pattern that - * is matching a line and everyone will be happy. - */ - -%option never-interactive -%option noyywrap -%option reentrant - -%{ -#include <string.h> -#include <openbsc/telnet_interface.h> - -extern char *strndup(const char *s, size_t n); -extern void telnet_write_help(int); -extern void telnet_close_client(struct bsc_fd*); -extern void telnet_error_client(int fd); -extern void telnet_page(struct telnet_connection *con, const char *imsi, int page); -extern void telnet_call(struct telnet_connection *con, const char *imsi, - const char* origin); -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* - -/* the string is null terminated */ -static int parse_hex(char *hex) -{ - int byte; - sscanf(hex, "%x", &byte); - return byte; -} - -#define PREPARE_STRING(len) \ - yytext[yyleng-1] = '\0'; \ - char *str = yytext + len; \ - char *pag = strstr(str, "\r"); \ - if (pag) pag[0] = '\0'; \ - pag = strstr(str, "\n"); \ - if (pag) pag[0] = '\0'; - -%} - -CMD_HELP "help" -CMD_EXIT "exit" -CMD_CLOSE "close" -CMD_PAGE "page" -CMD_GET_CHANNEL "get_channel" -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] - -%s READ_HEX_BYTES - -%% -{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); - yyterminate(); - } -{CMD_PAGE}[ ][0-9]+[ ][0-2]{LINE_END} { - PREPARE_STRING(PAGE_LEN) - char *sp = strstr(str, " "); - sp[0] = '\0'; - telnet_page(yyextra, str, atoi(sp+1)); - yyterminate(); - } -{CMD_PUT_CHANNEL}[ ][0-9]+{LINE_END} { - PREPARE_STRING(PUT_LEN) - telnet_put_channel(yyextra, str); - yyterminate(); - } -{CMD_GET_CHANNEL}[ ][0-9]+{LINE_END} { - PREPARE_STRING(GET_LEN) - telnet_get_channel(yyextra, str); - yyterminate(); - } -{CMD_CALL}[ ][0-9]+[ ][0-9]+{LINE_END} { - PREPARE_STRING(CALL_LEN) - char *sp = strstr(str, " "); - sp[0] = '\0'; - telnet_call(yyextra, str, sp+1); - yyterminate(); - } -{CMD_CALL}[ ][0-9]+{LINE_END} { - PREPARE_STRING(CALL_LEN) - telnet_call(yyextra, str, NULL); - yyterminate(); - } -<READ_HEX_BYTES>{HEX} { - if (yyextra->read >= sizeof(yyextra->commands)) { - yyterminate(); - } - yytext[yyleng] = '\0'; - yyextra->commands[yyextra->read++] = parse_hex(yytext+2); - } -<READ_HEX_BYTES>{LINE_END} { - if (yyextra->command == TELNET_COMMAND_11) { - telnet_send_gsm_11(yyextra); - } else if (yyextra->command == TELNET_COMMAND_48) { - telnet_send_gsm_48(yyextra); - } - - if (yyextra->imsi) { - free(yyextra->imsi); - yyextra->imsi = NULL; - } - yyterminate(); - } -<INITIAL>{CMD_48}[ ][0-9]+ { - BEGIN READ_HEX_BYTES; - yyextra->read = 0; - yyextra->command = TELNET_COMMAND_48; - yytext[yyleng-1] = '\0'; - yyextra->imsi = strdup(yytext); - } - -<INITIAL>{CMD_11}[ ][0-9]+ { - BEGIN READ_HEX_BYTES; - yyextra->read = 0; - yyextra->command = TELNET_COMMAND_11; - yytext[yyleng-1] = '\0'; - yyextra->imsi = strdup(yytext); - } - - - -[ \t\r\n] /* Ommit */ -. { telnet_error_client(yyextra->fd.fd); yyterminate(); } - -%% - -void telnet_parse(struct telnet_connection *conn, char *buf) -{ - yyscan_t scanner; - yylex_init(&scanner); - yyset_extra(conn, scanner); - yy_scan_string(buf, scanner); - yylex(scanner); - yylex_destroy(scanner); - - if (conn->imsi) { - free(conn->imsi); - conn->imsi = NULL; - } -} - -__attribute__((unused)) void telnet_unused(void) -{ - yyunput(0, 0, 0); - input(0); -} |