Merge branch 'master' into sms
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 52dec90..d6f95f6 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -381,6 +381,7 @@
struct gsm_bts_trx *gsm_bts_trx_num(struct gsm_bts *bts, int num);
const char *gsm_pchan_name(enum gsm_phys_chan_config c);
+enum gsm_phys_chan_config gsm_pchan_parse(const char *name);
const char *gsm_lchan_name(enum gsm_chan_t c);
const char *gsm_chreq_name(enum gsm_chreq_reason_t c);
char *gsm_ts_name(struct gsm_bts_trx_ts *ts);
diff --git a/openbsc/include/vty/vty.h b/openbsc/include/vty/vty.h
index 4bb785b..d43d992 100644
--- a/openbsc/include/vty/vty.h
+++ b/openbsc/include/vty/vty.h
@@ -26,6 +26,7 @@
VTY_SERV,
VTY_READ,
VTY_WRITE,
+ VTY_CLOSED,
VTY_TIMEOUT_RESET,
#ifdef VTYSH
VTYSH_SERV,
diff --git a/openbsc/src/bsc_hack.c b/openbsc/src/bsc_hack.c
index 82cb788..9e0a260 100644
--- a/openbsc/src/bsc_hack.c
+++ b/openbsc/src/bsc_hack.c
@@ -1320,11 +1320,13 @@
switch (signal) {
case SIGINT:
- case SIGABRT:
shutdown_net(gsmnet);
sleep(3);
exit(0);
break;
+ case SIGABRT:
+ /* in case of abort, we want to obtain a talloc report
+ * and then return to the caller, who will abort the process */
case SIGUSR1:
talloc_report_full(tall_bsc_ctx, stderr);
break;
diff --git a/openbsc/src/gsm_data.c b/openbsc/src/gsm_data.c
index 285b758..0ed0845 100644
--- a/openbsc/src/gsm_data.c
+++ b/openbsc/src/gsm_data.c
@@ -55,6 +55,18 @@
return pchan_names[c];
}
+enum gsm_phys_chan_config gsm_pchan_parse(const char *name)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pchan_names); i++) {
+ if (!strcasecmp(name, pchan_names[i]))
+ return i;
+ }
+
+ return -1;
+}
+
static const char *lchan_names[] = {
[GSM_LCHAN_NONE] = "NONE",
[GSM_LCHAN_SDCCH] = "SDCCH",
diff --git a/openbsc/src/telnet_interface.c b/openbsc/src/telnet_interface.c
index 7a67fe1..ba57470 100644
--- a/openbsc/src/telnet_interface.c
+++ b/openbsc/src/telnet_interface.c
@@ -146,6 +146,10 @@
rc = vty_read(conn->vty);
}
+ /* vty might have been closed from vithin vty_read() */
+ if (!conn->vty)
+ return rc;
+
if (what & BSC_FD_WRITE) {
rc = buffer_flush_all(conn->vty->obuf, fd->fd);
if (rc == BUFFER_EMPTY)
@@ -192,6 +196,9 @@
struct telnet_connection *connection = vty->priv;
struct bsc_fd *bfd = &connection->fd;
+ if (vty->type != VTY_TERM)
+ return;
+
switch (event) {
case VTY_READ:
bfd->when |= BSC_FD_READ;
@@ -199,6 +206,11 @@
case VTY_WRITE:
bfd->when |= BSC_FD_WRITE;
break;
+ case VTY_CLOSED:
+ /* vty layer is about to free() vty */
+ connection->vty = NULL;
+ telnet_close_client(bfd);
+ break;
default:
break;
}
diff --git a/openbsc/src/vty/buffer.c b/openbsc/src/vty/buffer.c
index 6366100..be6623d 100644
--- a/openbsc/src/vty/buffer.c
+++ b/openbsc/src/vty/buffer.c
@@ -28,9 +28,12 @@
#include <stddef.h>
#include <sys/uio.h>
+#include <openbsc/talloc.h>
#include <vty/buffer.h>
#include <vty/vty.h>
+static void *tall_vbuf_ctx;
+
/* Buffer master. */
struct buffer {
/* Data list. */
@@ -61,14 +64,14 @@
next page boundery. */
#define BUFFER_SIZE_DEFAULT 4096
-#define BUFFER_DATA_FREE(D) free((D))
+#define BUFFER_DATA_FREE(D) talloc_free((D))
/* Make new buffer. */
struct buffer *buffer_new(size_t size)
{
struct buffer *b;
- b = calloc(1, sizeof(struct buffer));
+ b = talloc_zero(tall_vbuf_ctx, struct buffer);
if (size)
b->size = size;
@@ -89,7 +92,7 @@
void buffer_free(struct buffer *b)
{
buffer_reset(b);
- free(b);
+ talloc_free(b);
}
/* Make string clone. */
@@ -102,7 +105,7 @@
for (data = b->head; data; data = data->next)
totlen += data->cp - data->sp;
- if (!(s = malloc(totlen + 1)))
+ if (!(s = _talloc_zero(tall_vbuf_ctx, (totlen + 1), "buffer_getstr")))
return NULL;
p = s;
for (data = b->head; data; data = data->next) {
@@ -137,7 +140,9 @@
{
struct buffer_data *d;
- d = malloc(offsetof(struct buffer_data, data[b->size]));
+ d = _talloc_zero(tall_vbuf_ctx,
+ offsetof(struct buffer_data, data[b->size]),
+ "buffer_add");
if (!d)
return NULL;
d->cp = d->sp = 0;
@@ -458,3 +463,8 @@
}
return b->head ? BUFFER_PENDING : BUFFER_EMPTY;
}
+
+static __attribute__((constructor)) void on_dso_load_vty_buf(void)
+{
+ tall_vbuf_ctx = talloc_named_const(NULL, 1, "vty_buffer");
+}
diff --git a/openbsc/src/vty/command.c b/openbsc/src/vty/command.c
index 44bdf26..9841343 100644
--- a/openbsc/src/vty/command.c
+++ b/openbsc/src/vty/command.c
@@ -47,6 +47,9 @@
#include <openbsc/gsm_data.h>
#include <openbsc/gsm_subscriber.h>
+#include <openbsc/talloc.h>
+
+static void *tall_vcmd_ctx;
/* Command vector which includes some level of command lists. Normally
each daemon maintains each own cmdvec. */
@@ -172,7 +175,7 @@
len += strlen(argv[i]) + 1;
if (!len)
return NULL;
- p = str = malloc(len);
+ p = str = _talloc_zero(tall_vcmd_ctx, len, "arvg_concat");
for (i = shift; i < argc; i++) {
size_t arglen;
memcpy(p, argv[i], (arglen = strlen(argv[i])));
@@ -274,7 +277,7 @@
*cp != '\0')
cp++;
strlen = cp - start;
- token = malloc(strlen + 1);
+ token = _talloc_zero(tall_vcmd_ctx, strlen + 1, "make_strvec");
memcpy(token, start, strlen);
*(token + strlen) = '\0';
vector_set(strvec, token);
@@ -299,7 +302,7 @@
for (i = 0; i < vector_active(v); i++)
if ((cp = vector_slot(v, i)) != NULL)
- free(cp);
+ talloc_free(cp);
vector_free(v);
}
@@ -330,7 +333,7 @@
cp++;
strlen = cp - start;
- token = malloc(strlen + 1);
+ token = _talloc_zero(tall_vcmd_ctx, strlen + 1, "cmd_desc_str");
memcpy(token, start, strlen);
*(token + strlen) = '\0';
@@ -401,11 +404,11 @@
len = cp - sp;
- token = malloc(len + 1);
+ token = _talloc_zero(tall_vcmd_ctx, len + 1, "cmd_make_descvec");
memcpy(token, sp, len);
*(token + len) = '\0';
- desc = calloc(1, sizeof(struct desc));
+ desc = talloc_zero(tall_vcmd_ctx, struct desc);
desc->cmd = token;
desc->str = cmd_desc_str(&dp);
@@ -1852,7 +1855,8 @@
if (len < lcd) {
char *lcdstr;
- lcdstr = malloc(lcd + 1);
+ lcdstr = _talloc_zero(tall_vcmd_ctx, lcd + 1,
+ "complete-lcdstr");
memcpy(lcdstr, matchvec->index[0], lcd);
lcdstr[lcd] = '\0';
@@ -1861,7 +1865,7 @@
/* Free matchvec. */
for (i = 0; i < vector_active(matchvec); i++) {
if (vector_slot(matchvec, i))
- free(vector_slot(matchvec, i));
+ talloc_free(vector_slot(matchvec, i));
}
vector_free(matchvec);
@@ -2472,11 +2476,14 @@
config_file = host.config;
config_file_sav =
- malloc(strlen(config_file) + strlen(CONF_BACKUP_EXT) + 1);
+ _talloc_zero(tall_vcmd_ctx,
+ strlen(config_file) + strlen(CONF_BACKUP_EXT) + 1,
+ "config_file_sav");
strcpy(config_file_sav, config_file);
strcat(config_file_sav, CONF_BACKUP_EXT);
- config_file_tmp = malloc(strlen(config_file) + 8);
+ config_file_tmp = _talloc_zero(tall_vcmd_ctx, strlen(config_file) + 8,
+ "config_file_tmp");
sprintf(config_file_tmp, "%s.XXXXXX", config_file);
/* Open file to configuration write. */
@@ -2484,8 +2491,8 @@
if (fd < 0) {
vty_out(vty, "Can't open configuration file %s.%s",
config_file_tmp, VTY_NEWLINE);
- free(config_file_tmp);
- free(config_file_sav);
+ talloc_free(config_file_tmp);
+ talloc_free(config_file_sav);
return CMD_WARNING;
}
@@ -2495,7 +2502,7 @@
file_vty->type = VTY_FILE;
/* Config file header print. */
- vty_out(file_vty, "!\n! Zebra configuration saved from vty\n! ");
+ vty_out(file_vty, "!\n! OpenBSC configuration saved from vty\n! ");
//vty_time_print (file_vty, 1);
vty_out(file_vty, "!\n");
@@ -2511,16 +2518,16 @@
vty_out(vty,
"Can't unlink backup configuration file %s.%s",
config_file_sav, VTY_NEWLINE);
- free(config_file_sav);
- free(config_file_tmp);
+ talloc_free(config_file_sav);
+ talloc_free(config_file_tmp);
unlink(config_file_tmp);
return CMD_WARNING;
}
if (link(config_file, config_file_sav) != 0) {
vty_out(vty, "Can't backup old configuration file %s.%s",
config_file_sav, VTY_NEWLINE);
- free(config_file_sav);
- free(config_file_tmp);
+ talloc_free(config_file_sav);
+ talloc_free(config_file_tmp);
unlink(config_file_tmp);
return CMD_WARNING;
}
@@ -2528,24 +2535,24 @@
if (unlink(config_file) != 0) {
vty_out(vty, "Can't unlink configuration file %s.%s",
config_file, VTY_NEWLINE);
- free(config_file_sav);
- free(config_file_tmp);
+ talloc_free(config_file_sav);
+ talloc_free(config_file_tmp);
unlink(config_file_tmp);
return CMD_WARNING;
}
if (link(config_file_tmp, config_file) != 0) {
vty_out(vty, "Can't save configuration file %s.%s", config_file,
VTY_NEWLINE);
- free(config_file_sav);
- free(config_file_tmp);
+ talloc_free(config_file_sav);
+ talloc_free(config_file_tmp);
unlink(config_file_tmp);
return CMD_WARNING;
}
unlink(config_file_tmp);
sync();
- free(config_file_sav);
- free(config_file_tmp);
+ talloc_free(config_file_sav);
+ talloc_free(config_file_tmp);
if (chmod(config_file, CONFIGFILE_MASK) != 0) {
vty_out(vty, "Can't chmod configuration file %s: %s (%d).%s",
@@ -2654,7 +2661,7 @@
}
if (host.name)
- free(host.name);
+ talloc_free(host.name);
host.name = strdup(argv[0]);
return CMD_SUCCESS;
@@ -2666,7 +2673,7 @@
NO_STR "Reset system's network name\n" "Host name of this router\n")
{
if (host.name)
- free(host.name);
+ talloc_free(host.name);
host.name = NULL;
return CMD_SUCCESS;
}
@@ -2687,10 +2694,10 @@
if (argc == 2) {
if (*argv[0] == '8') {
if (host.password)
- free(host.password);
+ talloc_free(host.password);
host.password = NULL;
if (host.password_encrypt)
- free(host.password_encrypt);
+ talloc_free(host.password_encrypt);
host.password_encrypt = strdup(strdup(argv[1]));
return CMD_SUCCESS;
} else {
@@ -2707,13 +2714,13 @@
}
if (host.password)
- free(host.password);
+ talloc_free(host.password);
host.password = NULL;
#ifdef VTY_CRYPT_PW
if (host.encrypt) {
if (host.password_encrypt)
- free(host.password_encrypt);
+ talloc_free(host.password_encrypt);
host.password_encrypt = strdup(zencrypt(argv[0]));
} else
#endif
@@ -2745,11 +2752,11 @@
if (argc == 2) {
if (*argv[0] == '8') {
if (host.enable)
- free(host.enable);
+ talloc_free(host.enable);
host.enable = NULL;
if (host.enable_encrypt)
- free(host.enable_encrypt);
+ talloc_free(host.enable_encrypt);
host.enable_encrypt = strdup(argv[1]);
return CMD_SUCCESS;
@@ -2767,14 +2774,14 @@
}
if (host.enable)
- free(host.enable);
+ talloc_free(host.enable);
host.enable = NULL;
/* Plain password input. */
#ifdef VTY_CRYPT_PW
if (host.encrypt) {
if (host.enable_encrypt)
- free(host.enable_encrypt);
+ talloc_free(host.enable_encrypt);
host.enable_encrypt = strdup(zencrypt(argv[0]));
} else
#endif
@@ -2798,11 +2805,11 @@
"Assign the privileged level password\n")
{
if (host.enable)
- free(host.enable);
+ talloc_free(host.enable);
host.enable = NULL;
if (host.enable_encrypt)
- free(host.enable_encrypt);
+ talloc_free(host.enable_encrypt);
host.enable_encrypt = NULL;
return CMD_SUCCESS;
@@ -2821,12 +2828,12 @@
if (host.password) {
if (host.password_encrypt)
- free(host.password_encrypt);
+ talloc_free(host.password_encrypt);
host.password_encrypt = strdup(zencrypt(host.password));
}
if (host.enable) {
if (host.enable_encrypt)
- free(host.enable_encrypt);
+ talloc_free(host.enable_encrypt);
host.enable_encrypt = strdup(zencrypt(host.enable));
}
@@ -2844,11 +2851,11 @@
host.encrypt = 0;
if (host.password_encrypt)
- free(host.password_encrypt);
+ talloc_free(host.password_encrypt);
host.password_encrypt = NULL;
if (host.enable_encrypt)
- free(host.enable_encrypt);
+ talloc_free(host.enable_encrypt);
host.enable_encrypt = NULL;
return CMD_SUCCESS;
@@ -2924,7 +2931,7 @@
((message =
argv_concat(argv, argc, 0)) ? message : ""), VTY_NEWLINE);
if (message)
- free(message);
+ talloc_free(message);
return CMD_SUCCESS;
}
@@ -2944,7 +2951,7 @@
zlog(NULL, level,
((message = argv_concat(argv, argc, 1)) ? message : ""));
if (message)
- free(message);
+ talloc_free(message);
return CMD_SUCCESS;
}
@@ -3076,7 +3083,9 @@
return CMD_WARNING;
}
- if ((p = malloc(strlen(cwd) + strlen(fname) + 2))
+ if ((p = _talloc_zero(tall_vcmd_ctx,
+ strlen(cwd) + strlen(fname) + 2),
+ "set_log_file")
== NULL) {
zlog_err("config_log_file: Unable to alloc mem!");
return CMD_WARNING;
@@ -3089,7 +3098,7 @@
ret = zlog_set_file(NULL, fullpath, loglevel);
if (p)
- free(p);
+ talloc_free(p);
if (!ret) {
vty_out(vty, "can't open logfile %s\n", fname);
@@ -3097,7 +3106,7 @@
}
if (host.logfile)
- free(host.logfile);
+ talloc_free(host.logfile);
host.logfile = strdup(fname);
@@ -3134,7 +3143,7 @@
zlog_reset_file(NULL);
if (host.logfile)
- free(host.logfile);
+ talloc_free(host.logfile);
host.logfile = NULL;
@@ -3288,7 +3297,7 @@
"Set banner\n" "Banner for motd\n" "Banner from a file\n" "Filename\n")
{
if (host.motdfile)
- free(host.motdfile);
+ talloc_free(host.motdfile);
host.motdfile = strdup(argv[0]);
return CMD_SUCCESS;
@@ -3309,7 +3318,7 @@
{
host.motd = NULL;
if (host.motdfile)
- free(host.motdfile);
+ talloc_free(host.motdfile);
host.motdfile = NULL;
return CMD_SUCCESS;
}
@@ -3412,3 +3421,8 @@
}
srand(time(NULL));
}
+
+static __attribute__((constructor)) void on_dso_load_vty_command(void)
+{
+ tall_vcmd_ctx = talloc_named_const(NULL, 1, "vty_command");
+}
diff --git a/openbsc/src/vty/vector.c b/openbsc/src/vty/vector.c
index 7687010..c8885a4 100644
--- a/openbsc/src/vty/vector.c
+++ b/openbsc/src/vty/vector.c
@@ -23,12 +23,15 @@
#include <unistd.h>
#include <vty/vector.h>
+#include <openbsc/talloc.h>
#include <memory.h>
+static void *tall_vvec_ctx;
+
/* Initialize vector : allocate memory and return vector. */
vector vector_init(unsigned int size)
{
- vector v = calloc(1, sizeof(struct _vector));
+ vector v = talloc_zero(tall_vvec_ctx, struct _vector);
if (!v)
return NULL;
@@ -38,9 +41,10 @@
v->alloced = size;
v->active = 0;
- v->index = calloc(1, sizeof(void *) * size);
+ v->index = _talloc_zero(tall_vvec_ctx, sizeof(void *) * size,
+ "vector_init:index");
if (!v->index) {
- free(v);
+ talloc_free(v);
return NULL;
}
return v;
@@ -48,24 +52,24 @@
void vector_only_wrapper_free(vector v)
{
- free(v);
+ talloc_free(v);
}
void vector_only_index_free(void *index)
{
- free(index);
+ talloc_free(index);
}
void vector_free(vector v)
{
- free(v->index);
- free(v);
+ talloc_free(v->index);
+ talloc_free(v);
}
vector vector_copy(vector v)
{
unsigned int size;
- vector new = calloc(1, sizeof(struct _vector));
+ vector new = talloc_zero(tall_vvec_ctx, struct _vector);
if (!new)
return NULL;
@@ -73,9 +77,9 @@
new->alloced = v->alloced;
size = sizeof(void *) * (v->alloced);
- new->index = calloc(1, size);
+ new->index = _talloc_zero(tall_vvec_ctx, size, "vector_copy:index");
if (!new->index) {
- free(new);
+ talloc_free(new);
return NULL;
}
memcpy(new->index, v->index, size);
@@ -89,7 +93,8 @@
if (v->alloced > num)
return;
- v->index = realloc(v->index, sizeof(void *) * (v->alloced * 2));
+ v->index = talloc_realloc_size(tall_vvec_ctx, v->index,
+ sizeof(void *) * (v->alloced * 2));
memset(&v->index[v->alloced], 0, sizeof(void *) * v->alloced);
v->alloced *= 2;
@@ -184,3 +189,8 @@
return count;
}
+
+static __attribute__((constructor)) void on_dso_load_vty_vec(void)
+{
+ tall_vvec_ctx = talloc_named_const(NULL, 1, "vty_vector");
+}
diff --git a/openbsc/src/vty/vty.c b/openbsc/src/vty/vty.c
index c461631..0549914 100644
--- a/openbsc/src/vty/vty.c
+++ b/openbsc/src/vty/vty.c
@@ -17,6 +17,7 @@
#include <vty/vty.h>
#include <vty/command.h>
#include <vty/buffer.h>
+#include <openbsc/talloc.h>
extern struct host host;
@@ -32,6 +33,8 @@
static int no_password_check = 1;
+static void *tall_vty_ctx;
+
static void vty_clear_buf(struct vty *vty)
{
memset(vty->buf, 0, vty->max);
@@ -40,7 +43,7 @@
/* Allocate new vty struct. */
struct vty *vty_new()
{
- struct vty *new = malloc(sizeof(struct vty));
+ struct vty *new = talloc_zero(tall_vty_ctx, struct vty);
if (!new)
goto out;
@@ -48,7 +51,7 @@
new->obuf = buffer_new(0); /* Use default buffer size. */
if (!new->obuf)
goto out_new;
- new->buf = calloc(1, VTY_BUFSIZ);
+ new->buf = _talloc_zero(tall_vty_ctx, VTY_BUFSIZ, "vty_new->buf");
if (!new->buf)
goto out_obuf;
@@ -57,9 +60,9 @@
return new;
out_obuf:
- free(new->obuf);
+ buffer_free(new->obuf);
out_new:
- free(new);
+ talloc_free(new);
new = NULL;
out:
return new;
@@ -135,16 +138,19 @@
{
int i;
- /* Flush buffer. */
- buffer_flush_all(vty->obuf, vty->fd);
+ if (vty->obuf) {
+ /* Flush buffer. */
+ buffer_flush_all(vty->obuf, vty->fd);
- /* Free input buffer. */
- buffer_free(vty->obuf);
+ /* Free input buffer. */
+ buffer_free(vty->obuf);
+ vty->obuf = NULL;
+ }
/* Free command history. */
for (i = 0; i < VTY_MAXHIST; i++)
if (vty->hist[i])
- free(vty->hist[i]);
+ talloc_free(vty->hist[i]);
/* Unset vector. */
vector_unset(vtyvec, vty->fd);
@@ -153,17 +159,20 @@
if (vty->fd > 0)
close(vty->fd);
- if (vty->buf)
- free(vty->buf);
+ if (vty->buf) {
+ talloc_free(vty->buf);
+ vty->buf = NULL;
+ }
/* Check configure. */
vty_config_unlock(vty);
- /* OK free vty. */
- free(vty);
-
/* FIXME: memory leak. We need to call telnet_close_client() but don't
* have bfd */
+ vty_event(VTY_CLOSED, vty->fd, vty);
+
+ /* OK free vty. */
+ talloc_free(vty);
}
int vty_shell(struct vty *vty)
@@ -199,7 +208,7 @@
else
size = size * 2;
- p = realloc(p, size);
+ p = talloc_realloc_size(tall_vty_ctx, p, size);
if (!p)
return -1;
@@ -221,7 +230,7 @@
/* If p is not different with buf, it is allocated buffer. */
if (p != buf)
- free(p);
+ talloc_free(p);
}
return len;
@@ -344,7 +353,7 @@
{
if (vty->max <= length) {
vty->max *= 2;
- vty->buf = realloc(vty->buf, vty->max);
+ vty->buf = talloc_realloc_size(tall_vty_ctx, vty->buf, vty->max);
// FIXME: check return
}
}
@@ -444,8 +453,8 @@
/* Insert history entry. */
if (vty->hist[vty->hindex])
- free(vty->hist[vty->hindex]);
- vty->hist[vty->hindex] = strdup(vty->buf);
+ talloc_free(vty->hist[vty->hindex]);
+ vty->hist[vty->hindex] = talloc_strdup(tall_vty_ctx, vty->buf);
/* History index rotation. */
vty->hindex++;
@@ -918,14 +927,14 @@
vty_backward_pure_word(vty);
vty_insert_word_overwrite(vty, matched[0]);
vty_self_insert(vty, ' ');
- free(matched[0]);
+ //talloc_free(matched[0]);
break;
case CMD_COMPLETE_MATCH:
vty_prompt(vty);
vty_redraw_line(vty);
vty_backward_pure_word(vty);
vty_insert_word_overwrite(vty, matched[0]);
- free(matched[0]);
+ talloc_free(matched[0]);
vector_only_index_free(matched);
return;
break;
@@ -934,7 +943,7 @@
if (i != 0 && ((i % 6) == 0))
vty_out(vty, "%s", VTY_NEWLINE);
vty_out(vty, "%-10s ", matched[i]);
- free(matched[i]);
+ talloc_free(matched[i]);
}
vty_out(vty, "%s", VTY_NEWLINE);
@@ -968,7 +977,7 @@
return;
}
- buf = calloc(1, strlen(desc->str) + 1);
+ buf = _talloc_zero(tall_vty_ctx, strlen(desc->str) + 1, "describe_fold");
if (!buf)
return;
@@ -989,7 +998,7 @@
vty_out(vty, " %-*s %s%s", cmd_width, cmd, p, VTY_NEWLINE);
- free(buf);
+ talloc_free(buf);
}
/* Describe matched command function. */
@@ -1588,7 +1597,7 @@
getcwd(cwd, MAXPATHLEN);
}
- vty_cwd = malloc(strlen(cwd) + 1);
+ vty_cwd = _talloc_zero(tall_vty_ctx, strlen(cwd) + 1, "save_cwd");
strcpy(vty_cwd, cwd);
}
@@ -1613,6 +1622,8 @@
/* For further configuration read, preserve current directory. */
vty_save_cwd();
+ host.config = "openbsc.cfg";
+
vtyvec = vector_init(VECTOR_MIN_SIZE);
/* Install bgp top node. */
@@ -1635,3 +1646,8 @@
install_element(VTY_NODE, &no_vty_login_cmd);
#endif
}
+
+static __attribute__((constructor)) void on_dso_load_vty(void)
+{
+ tall_vty_ctx = talloc_named_const(NULL, 1, "vty");
+}
diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c
index b480c3d..e191443 100644
--- a/openbsc/src/vty_interface.c
+++ b/openbsc/src/vty_interface.c
@@ -189,8 +189,9 @@
VTY_NEWLINE);
vty_out(vty, "\ttraining_sequence_code %u%s", bts->tsc, VTY_NEWLINE);
vty_out(vty, "\tbase_station_id_code %u%s", bts->bsic, VTY_NEWLINE);
- vty_out(vty, "\tunit_id %u %u%s",
- bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
+ if (is_ipaccess_bts(bts))
+ vty_out(vty, "\tunit_id %u %u%s",
+ bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE);
llist_for_each_entry(trx, &bts->trx_list, list)
config_write_trx_single(vty, trx);
@@ -690,8 +691,8 @@
{
struct gsm_bts *bts = vty->index;
- /* FIXME: implementation */
- //bts->type =
+ bts->type = parse_btstype(argv[0]);
+
return CMD_SUCCESS;
}
@@ -894,6 +895,36 @@
return CMD_SUCCESS;
}
+DEFUN(cfg_ts_pchan,
+ cfg_ts_pchan_cmd,
+ "phys_chan_config PCHAN",
+ "Physical Channel configuration (TCH/SDCCH/...)")
+{
+ struct gsm_bts_trx_ts *ts = vty->index;
+ int pchanc;
+
+ pchanc = gsm_pchan_parse(argv[0]);
+ if (pchanc < 0)
+ return CMD_WARNING;
+
+ ts->pchan = pchanc;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ts_e1_subslot,
+ cfg_ts_e1_subslot_cmd,
+ "e1_subslot E1_IF <1-31> <0-4>",
+ "E1 sub-slot connected to this on-air timeslot")
+{
+ struct gsm_bts_trx_ts *ts = vty->index;
+
+ ts->e1_link.e1_nr = atoi(argv[0]);
+ ts->e1_link.e1_ts = atoi(argv[1]);
+ ts->e1_link.e1_ts_ss = atoi(argv[2]);
+
+ return CMD_SUCCESS;
+}
/* Subscriber */
DEFUN(show_subscr,
@@ -1010,6 +1041,8 @@
install_element(TRX_NODE, &cfg_ts_cmd);
install_node(&ts_node, dummy_config_write);
install_default(TS_NODE);
+ install_element(TS_NODE, &cfg_ts_pchan_cmd);
+ install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
install_element(CONFIG_NODE, &cfg_subscr_cmd);
install_node(&subscr_node, dummy_config_write);