aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2009-03-10 12:21:45 +0000
committerHarald Welte <laforge@gnumonks.org>2009-03-10 12:21:45 +0000
commit404cdd8951647b0f9ae9021cbc04798a05282a23 (patch)
treea7d3cd93fd57961d0487f3ec631f2951334d4086
parent68628e8479519ab49066b5b19f35a68884c6bab5 (diff)
make telnet interface use VTY code
-rw-r--r--include/openbsc/telnet_interface.h4
-rw-r--r--src/Makefile.am6
-rw-r--r--src/telnet_interface.c228
-rw-r--r--src/telnet_parser.l190
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);
-}