bsc: Add control command to set timezone

This adds a per BTS control command 'timezone' which expects a value
of the format '<hours>,<mins>,<dst>' or 'off' to set the value of
bts->tz. It has the same functionality like the existing VTY command
'timezone' in network/bts.

Sponsored-by: On-Waves ehf
Ticket: OW#978
This commit is contained in:
Jacob Erlbeck 2013-10-01 13:26:42 +02:00 committed by Holger Hans Peter Freyther
parent 55e34a3325
commit cc391b8880
2 changed files with 152 additions and 0 deletions

View File

@ -376,6 +376,117 @@ err:
return 1;
}
CTRL_CMD_DEFINE(bts_timezone, "timezone");
static int get_bts_timezone(struct ctrl_cmd *cmd, void *data)
{
struct gsm_bts *bts = (struct gsm_bts *) cmd->node;
if (!bts) {
cmd->reply = "bts not found.";
return CTRL_CMD_ERROR;
}
if (bts->tz.override)
cmd->reply = talloc_asprintf(cmd, "%d,%d,%d",
bts->tz.hr, bts->tz.mn, bts->tz.dst);
else
cmd->reply = talloc_asprintf(cmd, "off");
if (!cmd->reply) {
cmd->reply = "OOM";
return CTRL_CMD_ERROR;
}
return CTRL_CMD_REPLY;
}
static int set_bts_timezone(struct ctrl_cmd *cmd, void *data)
{
char *saveptr, *hourstr, *minstr, *dststr, *tmp = 0;
int override;
struct gsm_bts *bts = (struct gsm_bts *) cmd->node;
if (!bts) {
cmd->reply = "bts not found.";
return CTRL_CMD_ERROR;
}
tmp = talloc_strdup(cmd, cmd->value);
if (!tmp)
goto oom;
hourstr = strtok_r(tmp, ",", &saveptr);
minstr = strtok_r(NULL, ",", &saveptr);
dststr = strtok_r(NULL, ",", &saveptr);
override = 0;
if (hourstr != NULL)
override = strcasecmp(hourstr, "off") != 0;
bts->tz.override = override;
if (override) {
bts->tz.hr = hourstr ? atol(hourstr) : 0;
bts->tz.mn = minstr ? atol(minstr) : 0;
bts->tz.dst = dststr ? atol(dststr) : 0;
}
talloc_free(tmp);
tmp = NULL;
return get_bts_timezone(cmd, data);
oom:
cmd->reply = "OOM";
return CTRL_CMD_ERROR;
}
static int verify_bts_timezone(struct ctrl_cmd *cmd, const char *value, void *data)
{
char *saveptr, *hourstr, *minstr, *dststr, *tmp;
int override, tz_hours, tz_mins, tz_dst;
tmp = talloc_strdup(cmd, value);
if (!tmp)
return 1;
hourstr = strtok_r(tmp, ",", &saveptr);
minstr = strtok_r(NULL, ",", &saveptr);
dststr = strtok_r(NULL, ",", &saveptr);
if (hourstr == NULL)
goto err;
override = strcasecmp(hourstr, "off") != 0;
if (!override) {
talloc_free(tmp);
return 0;
}
if (minstr == NULL || dststr == NULL)
goto err;
tz_hours = atol(hourstr);
tz_mins = atol(minstr);
tz_dst = atol(dststr);
talloc_free(tmp);
tmp = NULL;
if ((tz_hours < -19) || (tz_hours > 19) ||
(tz_mins < 0) || (tz_mins >= 60) || (tz_mins % 15 != 0) ||
(tz_dst < 0) || (tz_dst > 2))
goto err;
return 0;
err:
talloc_free(tmp);
cmd->reply = talloc_strdup(cmd, "The format is <hours>,<mins>,<dst> or 'off' where -19 <= hours <= 19, mins in {0, 15, 30, 45}, and 0 <= dst <= 2");
return 1;
}
CTRL_CMD_DEFINE(bts_rf_state, "rf_state");
static int get_bts_rf_state(struct ctrl_cmd *cmd, void *data)
{
@ -493,6 +604,9 @@ int bsc_ctrl_cmds_install(struct gsm_network *net)
if (rc)
goto end;
rc = ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_loc);
if (rc)
goto end;
rc = ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_timezone);
if (rc)
goto end;
rc = ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_rf_lock);

View File

@ -201,6 +201,44 @@ class TestCtrlBSC(TestCtrlBase):
self.assertEquals(r['var'], 'bts.0.rf_state')
self.assertEquals(r['value'], 'inoperational,unlocked,on')
def testTimezone(self):
r = self.do_get('bts.0.timezone')
self.assertEquals(r['mtype'], 'GET_REPLY')
self.assertEquals(r['var'], 'bts.0.timezone')
self.assertEquals(r['value'], 'off')
r = self.do_set('bts.0.timezone', '-2,15,2')
self.assertEquals(r['mtype'], 'SET_REPLY')
self.assertEquals(r['var'], 'bts.0.timezone')
self.assertEquals(r['value'], '-2,15,2')
r = self.do_get('bts.0.timezone')
self.assertEquals(r['mtype'], 'GET_REPLY')
self.assertEquals(r['var'], 'bts.0.timezone')
self.assertEquals(r['value'], '-2,15,2')
# Test invalid input
r = self.do_set('bts.0.timezone', '-2,15,2,5,6,7')
self.assertEquals(r['mtype'], 'SET_REPLY')
self.assertEquals(r['var'], 'bts.0.timezone')
self.assertEquals(r['value'], '-2,15,2')
r = self.do_set('bts.0.timezone', '-2,15')
self.assertEquals(r['mtype'], 'ERROR')
r = self.do_set('bts.0.timezone', '-2')
self.assertEquals(r['mtype'], 'ERROR')
r = self.do_set('bts.0.timezone', '1')
r = self.do_set('bts.0.timezone', 'off')
self.assertEquals(r['mtype'], 'SET_REPLY')
self.assertEquals(r['var'], 'bts.0.timezone')
self.assertEquals(r['value'], 'off')
r = self.do_get('bts.0.timezone')
self.assertEquals(r['mtype'], 'GET_REPLY')
self.assertEquals(r['var'], 'bts.0.timezone')
self.assertEquals(r['value'], 'off')
def add_bsc_test(suite, workdir):
if not os.path.isfile(os.path.join(workdir, "src/osmo-bsc/osmo-bsc")):
print("Skipping the BSC test")