#include <unistd.h>
#include <sys/types.h>
-#include <osmocore/utils.h>
-#include <osmocore/gsm48.h>
-#include <osmocore/talloc.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/gsm/gsm48.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/signal.h>
#include <osmocom/bb/common/osmocom_data.h>
#include <osmocom/bb/common/networks.h>
+#include <osmocom/bb/common/gps.h>
#include <osmocom/bb/mobile/mncc.h>
#include <osmocom/bb/mobile/transaction.h>
#include <osmocom/bb/mobile/vty.h>
-#include <osmocom/bb/mobile/gps.h>
+#include <osmocom/bb/mobile/app_mobile.h>
#include <osmocom/vty/telnet_interface.h>
void *l23_ctx;
int mncc_answer(struct osmocom_ms *ms);
int mncc_hold(struct osmocom_ms *ms);
int mncc_retrieve(struct osmocom_ms *ms, int number);
+int mncc_dtmf(struct osmocom_ms *ms, char *dtmf);
extern struct llist_head ms_list;
extern struct llist_head active_connections;
}
int vty_reading = 0;
+static int hide_default = 0;
-static void vty_restart(struct vty *vty)
+static void vty_restart(struct vty *vty, struct osmocom_ms *ms)
{
if (vty_reading)
return;
- vty_out(vty, "You must restart for change to take effect!%s",
- VTY_NEWLINE);
+ if (ms->shutdown != 0)
+ return;
+ vty_out(vty, "You must restart MS '%s' ('shutdown / no shutdown') for "
+ "change to take effect!%s", ms->name, VTY_NEWLINE);
}
static struct osmocom_ms *get_ms(const char *name, struct vty *vty)
struct osmocom_ms *ms;
llist_for_each_entry(ms, &ms_list, entity) {
- if (!strcmp(ms->name, name))
+ if (!strcmp(ms->name, name)) {
+ if (ms->shutdown) {
+ vty_out(vty, "MS '%s' is admin down.%s", name,
+ VTY_NEWLINE);
+ return NULL;
+ }
return ms;
+ }
}
vty_out(vty, "MS name '%s' does not exits.%s", name, VTY_NEWLINE);
return NULL;
}
-DEFUN(show_ms, show_ms_cmd, "show ms",
- SHOW_STR "Display available MS entities\n")
-{
- struct osmocom_ms *ms;
-
- llist_for_each_entry(ms, &ms_list, entity) {
- struct gsm_settings *set = &ms->settings;
-
- vty_out(vty, "MS NAME: %s%s", ms->name, VTY_NEWLINE);
- vty_out(vty, " IMEI: %s%s", set->imei, VTY_NEWLINE);
- vty_out(vty, " IMEISV: %s%s", set->imeisv, VTY_NEWLINE);
- if (set->imei_random)
- vty_out(vty, " IMEI generation: random (%d trailing "
- "digits)%s", set->imei_random, VTY_NEWLINE);
- else
- vty_out(vty, " IMEI generation: fixed%s", VTY_NEWLINE);
- vty_out(vty, " network selection mode: %s%s",
- (set->plmn_mode == PLMN_MODE_AUTO)
- ? "automatic" : "manual", VTY_NEWLINE);
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN(show_support, show_support_cmd, "show support [ms_name]",
- SHOW_STR "Display information about MS support\n"
- "Name of MS (see \"show ms\")")
+static void gsm_ms_dump(struct osmocom_ms *ms, struct vty *vty)
{
- struct osmocom_ms *ms;
-
- if (argc) {
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
- gsm_support_dump(ms, print_vty, vty);
- } else {
- llist_for_each_entry(ms, &ms_list, entity) {
- gsm_support_dump(ms, print_vty, vty);
- vty_out(vty, "%s", VTY_NEWLINE);
+ struct gsm_settings *set = &ms->settings;
+ struct gsm_trans *trans;
+ char *service = "";
+
+ if (!ms->started)
+ service = ", radio is not started";
+ else if (ms->mmlayer.state == GSM48_MM_ST_MM_IDLE) {
+ /* current MM idle state */
+ switch (ms->mmlayer.substate) {
+ case GSM48_MM_SST_NORMAL_SERVICE:
+ case GSM48_MM_SST_PLMN_SEARCH_NORMAL:
+ service = ", service is normal";
+ break;
+ case GSM48_MM_SST_LOC_UPD_NEEDED:
+ case GSM48_MM_SST_ATTEMPT_UPDATE:
+ service = ", service is limited (pending)";
+ break;
+ case GSM48_MM_SST_NO_CELL_AVAIL:
+ service = ", service is unavailable";
+ break;
+ default:
+ if (ms->subscr.sim_valid)
+ service = ", service is limited";
+ else
+ service = ", service is limited "
+ "(IMSI detached)";
+ break;
}
- }
+ } else
+ service = ", MM connection active";
- return CMD_SUCCESS;
-}
+ vty_out(vty, "MS '%s' is %s%s%s%s", ms->name,
+ (ms->shutdown) ? "administratively " : "",
+ (ms->shutdown || !ms->started) ? "down" : "up",
+ (!ms->shutdown) ? service : "",
+ VTY_NEWLINE);
+ vty_out(vty, " IMEI: %s%s", set->imei, VTY_NEWLINE);
+ vty_out(vty, " IMEISV: %s%s", set->imeisv, VTY_NEWLINE);
+ if (set->imei_random)
+ vty_out(vty, " IMEI generation: random (%d trailing "
+ "digits)%s", set->imei_random, VTY_NEWLINE);
+ else
+ vty_out(vty, " IMEI generation: fixed%s", VTY_NEWLINE);
-static void gsm_states_dump(struct osmocom_ms *ms, struct vty *vty)
-{
- struct gsm_settings *set = &ms->settings;
- struct gsm_trans *trans;
+ if (ms->shutdown)
+ return;
- vty_out(vty, "Current state of MS '%s'%s", ms->name, VTY_NEWLINE);
if (set->plmn_mode == PLMN_MODE_AUTO)
- vty_out(vty, " automatic network selection: %s%s",
+ vty_out(vty, " automatic network selection state: %s%s",
plmn_a_state_names[ms->plmn.state], VTY_NEWLINE);
else
- vty_out(vty, " manual network selection: %s%s",
+ vty_out(vty, " manual network selection state: %s%s",
plmn_m_state_names[ms->plmn.state], VTY_NEWLINE);
- vty_out(vty, " cell selection: %s",
+ vty_out(vty, " cell selection state: %s",
cs_state_names[ms->cellsel.state]);
if (ms->rrlayer.state == GSM48_RR_ST_IDLE && ms->cellsel.selected)
- vty_out(vty, " (ARFCN %d)", ms->cellsel.sel_arfcn);
+ vty_out(vty, " (ARFCN %s)",
+ gsm_print_arfcn(ms->cellsel.sel_arfcn));
vty_out(vty, "%s", VTY_NEWLINE);
- vty_out(vty, " radio ressource layer: %s%s",
+ vty_out(vty, " radio ressource layer state: %s%s",
gsm48_rr_state_names[ms->rrlayer.state], VTY_NEWLINE);
- vty_out(vty, " mobility management layer: %s",
+ vty_out(vty, " mobility management layer state: %s",
gsm48_mm_state_names[ms->mmlayer.state]);
if (ms->mmlayer.state == GSM48_MM_ST_MM_IDLE)
vty_out(vty, ", %s",
gsm48_mm_substate_names[ms->mmlayer.substate]);
vty_out(vty, "%s", VTY_NEWLINE);
llist_for_each_entry(trans, &ms->trans_list, entry) {
- vty_out(vty, " call control: %s%s",
+ vty_out(vty, " call control state: %s%s",
gsm48_cc_state_name(trans->cc.state), VTY_NEWLINE);
}
}
-DEFUN(show_states, show_states_cmd, "show states [ms_name]",
- SHOW_STR "Display current states of given MS\n"
+
+DEFUN(show_ms, show_ms_cmd, "show ms [MS_NAME]",
+ SHOW_STR "Display available MS entities\n")
+{
+ struct osmocom_ms *ms;
+
+ if (argc) {
+ llist_for_each_entry(ms, &ms_list, entity) {
+ if (!strcmp(ms->name, argv[0])) {
+ gsm_ms_dump(ms, vty);
+ return CMD_SUCCESS;
+ }
+ }
+ vty_out(vty, "MS name '%s' does not exits.%s", argv[0],
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ } else {
+ llist_for_each_entry(ms, &ms_list, entity) {
+ gsm_ms_dump(ms, vty);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(show_support, show_support_cmd, "show support [MS_NAME]",
+ SHOW_STR "Display information about MS support\n"
"Name of MS (see \"show ms\")")
{
struct osmocom_ms *ms;
ms = get_ms(argv[0], vty);
if (!ms)
return CMD_WARNING;
- gsm_states_dump(ms, vty);
+ gsm_support_dump(ms, print_vty, vty);
} else {
llist_for_each_entry(ms, &ms_list, entity) {
- gsm_states_dump(ms, vty);
+ gsm_support_dump(ms, print_vty, vty);
vty_out(vty, "%s", VTY_NEWLINE);
}
}
return CMD_SUCCESS;
}
-DEFUN(show_subscr, show_subscr_cmd, "show subscriber [ms_name]",
+DEFUN(show_subscr, show_subscr_cmd, "show subscriber [MS_NAME]",
SHOW_STR "Display information about subscriber\n"
"Name of MS (see \"show ms\")")
{
gsm_subscr_dump(&ms->subscr, print_vty, vty);
} else {
llist_for_each_entry(ms, &ms_list, entity) {
- gsm_subscr_dump(&ms->subscr, print_vty, vty);
- vty_out(vty, "%s", VTY_NEWLINE);
+ if (!ms->shutdown) {
+ gsm_subscr_dump(&ms->subscr, print_vty, vty);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
}
}
return CMD_SUCCESS;
}
-DEFUN(show_cell_si, show_cell_si_cmd, "show cell MS_NAME <0-1023>",
+DEFUN(show_cell_si, show_cell_si_cmd, "show cell MS_NAME <0-1023> [pcs]",
SHOW_STR "Display information about received cell\n"
- "Name of MS (see \"show ms\")\nRadio frequency number")
+ "Name of MS (see \"show ms\")\nRadio frequency number\n"
+ "Given frequency is PCS band (1900) rather than DCS band.")
{
struct osmocom_ms *ms;
- int i;
struct gsm48_sysinfo *s;
+ uint16_t arfcn = atoi(argv[1]);
ms = get_ms(argv[0], vty);
if (!ms)
return CMD_WARNING;
- i = atoi(argv[1]);
- if (i < 0 || i > 1023) {
- vty_out(vty, "Given ARFCN '%s' not in range (0..1023)%s",
- argv[1], VTY_NEWLINE);
- return CMD_WARNING;
+ if (argc > 2) {
+ if (arfcn < 512 || arfcn > 810) {
+ vty_out(vty, "Given ARFCN not in PCS band%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ arfcn |= ARFCN_PCS;
}
- s = ms->cellsel.list[i].sysinfo;
+
+ s = ms->cellsel.list[arfcn2index(arfcn)].sysinfo;
if (!s) {
vty_out(vty, "Given ARFCN '%s' has no sysinfo available%s",
argv[1], VTY_NEWLINE);
return CMD_SUCCESS;
}
- gsm48_sysinfo_dump(s, i, print_vty, vty);
+ gsm48_sysinfo_dump(s, arfcn, print_vty, vty, ms->settings.freq_map);
return CMD_SUCCESS;
}
-DEFUN(show_ba, show_ba_cmd, "show ba MS_NAME [mcc] [mnc]",
+DEFUN(show_ba, show_ba_cmd, "show ba MS_NAME [MCC] [MNC]",
SHOW_STR "Display information about band allocations\n"
"Name of MS (see \"show ms\")\nMobile Country Code\n"
"Mobile Network Code")
return CMD_SUCCESS;
}
-DEFUN(sim_test, sim_test_cmd, "sim testcard MS_NAME [mcc] [mnc]",
+DEFUN(sim_test, sim_test_cmd, "sim testcard MS_NAME [MCC] [MNC] [LAC] [TMSI]",
"SIM actions\nInsert test card\nName of MS (see \"show ms\")\n"
- "Mobile Country Code of RPLMN\nMobile Network Code of RPLMN")
+ "Mobile Country Code of RPLMN\nMobile Network Code of RPLMN\n"
+ "Optionally locatio area code\nOptionally current assigned TMSI")
{
struct osmocom_ms *ms;
- uint16_t mcc = 0x001, mnc = 0x01f;
+ uint16_t mcc = 0x001, mnc = 0x01f, lac = 0x0000;
+ uint32_t tmsi = 0xffffffff;
ms = get_ms(argv[0], vty);
if (!ms)
}
}
- gsm_subscr_testcard(ms, mcc, mnc);
+ if (argc >= 4)
+ lac = strtoul(argv[3], NULL, 16);
+
+ if (argc >= 5)
+ tmsi = strtoul(argv[4], NULL, 16);
+
+ gsm_subscr_testcard(ms, mcc, mnc, lac, tmsi);
return CMD_SUCCESS;
}
return CMD_SUCCESS;
}
-DEFUN(call_retr, call_retr_cmd, "call MS_NAME retrieve [number]",
+DEFUN(call_retr, call_retr_cmd, "call MS_NAME retrieve [NUMBER]",
"Make a call\nName of MS (see \"show ms\")\n"
"Retrieve call on hold\nNumber of call to retrieve")
{
return CMD_SUCCESS;
}
+DEFUN(call_dtmf, call_dtmf_cmd, "call MS_NAME dtmf DIGITS",
+ "Make a call\nName of MS (see \"show ms\")\n"
+ "One or more DTMF digits to transmit")
+{
+ struct osmocom_ms *ms;
+ struct gsm_settings *set;
+
+ ms = get_ms(argv[0], vty);
+ if (!ms)
+ return CMD_WARNING;
+ set = &ms->settings;
+
+ if (!set->cc_dtmf) {
+ vty_out(vty, "DTMF not supported, please enable!%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ mncc_dtmf(ms, (char *)argv[1]);
+
+ return CMD_SUCCESS;
+}
+
DEFUN(network_show, network_show_cmd, "network show MS_NAME",
"Network ...\nShow results of network search (again)\n"
"Name of MS (see \"show ms\")")
DEFUN(cfg_gps_enable, cfg_gps_enable_cmd, "gps enable",
"GPS receiver")
{
- if (gps_open()) {
- gps.enable = 1;
+ if (osmo_gps_open()) {
+ g.enable = 1;
vty_out(vty, "Failed to open GPS device!%s", VTY_NEWLINE);
return CMD_WARNING;
}
- gps.enable = 1;
+ g.enable = 1;
return CMD_SUCCESS;
}
DEFUN(cfg_no_gps_enable, cfg_no_gps_enable_cmd, "no gps enable",
NO_STR "Disable GPS receiver")
{
- if (gps.enable)
- gps_close();
- gps.enable = 0;
+ if (g.enable)
+ osmo_gps_close();
+ g.enable = 0;
return CMD_SUCCESS;
}
+#ifdef _HAVE_GPSD
+DEFUN(cfg_gps_host, cfg_gps_host_cmd, "gps host HOST:PORT",
+ "GPS receiver\nSelect gpsd host and port\n"
+ "IP and port (optional) of the host running gpsd")
+{
+ char* colon = strstr(argv[0], ":");
+ if (colon != NULL) {
+ memcpy(g.gpsd_host, argv[0], colon - argv[0] - 1);
+ g.gpsd_host[colon - argv[0]] = '\0';
+ memcpy(g.gpsd_port, colon, strlen(colon));
+ g.gpsd_port[strlen(colon)] = '\0';
+ } else {
+ snprintf(g.gpsd_host, ARRAY_SIZE(g.gpsd_host), "%s", argv[0]);
+ g.gpsd_host[ARRAY_SIZE(g.gpsd_host) - 1] = '\0';
+ snprintf(g.gpsd_port, ARRAY_SIZE(g.gpsd_port), "2947");
+ g.gpsd_port[ARRAY_SIZE(g.gpsd_port) - 1] = '\0';
+ }
+ g.gps_type = GPS_TYPE_GPSD;
+ if (g.enable) {
+ osmo_gps_close();
+ if (osmo_gps_open()) {
+ vty_out(vty, "Failed to connect to gpsd host!%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+#endif
+
DEFUN(cfg_gps_device, cfg_gps_device_cmd, "gps device DEVICE",
"GPS receiver\nSelect serial device\n"
"Full path of serial device including /dev/")
{
- strncpy(gps.device, argv[0], sizeof(gps.device));
- gps.device[sizeof(gps.device) - 1] = '\0';
- if (gps.enable) {
- gps_close();
- if (gps_open()) {
+ strncpy(g.device, argv[0], sizeof(g.device));
+ g.device[sizeof(g.device) - 1] = '\0';
+ g.gps_type = GPS_TYPE_SERIAL;
+ if (g.enable) {
+ osmo_gps_close();
+ if (osmo_gps_open()) {
vty_out(vty, "Failed to open GPS device!%s",
VTY_NEWLINE);
return CMD_WARNING;
"GPS receiver\nSelect baud rate\nDefault, don't modify\n\n\n\n\n\n")
{
if (argv[0][0] == 'd')
- gps.baud = 0;
+ g.baud = 0;
else
- gps.baud = atoi(argv[0]);
- if (gps.enable) {
- gps_close();
- if (gps_open()) {
- gps.enable = 0;
+ g.baud = atoi(argv[0]);
+ if (g.enable) {
+ osmo_gps_close();
+ if (osmo_gps_open()) {
+ g.enable = 0;
vty_out(vty, "Failed to open GPS device!%s",
VTY_NEWLINE);
return CMD_WARNING;
return CMD_SUCCESS;
}
+DEFUN(cfg_hide_default, cfg_hide_default_cmd, "hide-default",
+ "Hide most default values in config to make it more compact")
+{
+ hide_default = 1;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_no_hide_default, cfg_no_hide_default_cmd, "no hide-default",
+ NO_STR "Show default values in config")
+{
+ hide_default = 0;
+
+ return CMD_SUCCESS;
+}
+
/* per MS config */
DEFUN(cfg_ms, cfg_ms_cmd, "ms MS_NAME",
"Select a mobile station to configure\nName of MS (see \"show ms\")")
{
struct osmocom_ms *ms;
+ int found = 0;
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
+ llist_for_each_entry(ms, &ms_list, entity) {
+ if (!strcmp(ms->name, argv[0])) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ if (!vty_reading) {
+ vty_out(vty, "MS name '%s' does not exits, try "
+ "'ms %s create'%s", argv[0], argv[0],
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ ms = mobile_new((char *)argv[0]);
+ if (!ms) {
+ vty_out(vty, "Failed to add MS name '%s'%s", argv[0],
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ vty->index = ms;
+ vty->node = MS_NODE;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ms_create, cfg_ms_create_cmd, "ms MS_NAME create",
+ "Select a mobile station to configure\nName of MS (see \"show ms\")\n"
+ "Create if MS does not exists")
+{
+ struct osmocom_ms *ms;
+ int found = 0;
+
+ llist_for_each_entry(ms, &ms_list, entity) {
+ if (!strcmp(ms->name, argv[0])) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ ms = mobile_new((char *)argv[0]);
+ if (!ms) {
+ vty_out(vty, "Failed to add MS name '%s'%s", argv[0],
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
vty->index = ms;
vty->node = MS_NODE;
+ vty_out(vty, "MS '%s' created, after configuration, do 'no shutdown'%s",
+ argv[0], VTY_NEWLINE);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ms_rename, cfg_ms_rename_cmd, "ms MS_NAME rename MS_NAME",
+ "Select a mobile station to configure\nName of MS (see \"show ms\")\n"
+ "Rename MS\nNew name of MS")
+{
+ struct osmocom_ms *ms;
+ int found = 0;
+
+ llist_for_each_entry(ms, &ms_list, entity) {
+ if (!strcmp(ms->name, argv[0])) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ vty_out(vty, "MS name '%s' does not exist%s", argv[0],
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ strncpy(ms->name, argv[1], sizeof(ms->name) - 1);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_no_ms, cfg_no_ms_cmd, "no ms MS_NAME",
+ NO_STR "Select a mobile station to remove\n"
+ "Name of MS (see \"show ms\")")
+{
+ struct osmocom_ms *ms;
+ int found = 0;
+
+ llist_for_each_entry(ms, &ms_list, entity) {
+ if (!strcmp(ms->name, argv[0])) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ vty_out(vty, "MS name '%s' does not exist%s", argv[0],
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ mobile_delete(ms, 1);
+
return CMD_SUCCESS;
}
#define SUP_WRITE(item, cmd) \
if (sup->item) \
- vty_out(vty, " %s%s%s", (set->item) ? "" : "no ", cmd, \
- VTY_NEWLINE);
+ if (!hide_default || !set->item) \
+ vty_out(vty, " %s%s%s", (set->item) ? "" : "no ", \
+ cmd, VTY_NEWLINE);
-static void config_write_ms_single(struct vty *vty, struct osmocom_ms *ms)
+static void config_write_ms(struct vty *vty, struct osmocom_ms *ms)
{
struct gsm_settings *set = &ms->settings;
struct gsm_support *sup = &ms->support;
struct gsm_settings_abbrev *abbrev;
vty_out(vty, "ms %s%s", ms->name, VTY_NEWLINE);
+ vty_out(vty, " layer2-socket %s%s", set->layer2_socket_path,
+ VTY_NEWLINE);
+ vty_out(vty, " sap-socket %s%s", set->sap_socket_path, VTY_NEWLINE);
switch(set->sim_type) {
case GSM_SIM_TYPE_NONE:
vty_out(vty, " sim none%s", VTY_NEWLINE);
vty_out(vty, " imei-random %d%s", set->imei_random,
VTY_NEWLINE);
else
- vty_out(vty, " imei-fixed%s", VTY_NEWLINE);
+ if (!hide_default)
+ vty_out(vty, " imei-fixed%s", VTY_NEWLINE);
if (set->emergency_imsi[0])
vty_out(vty, " emergency-imsi %s%s", set->emergency_imsi,
VTY_NEWLINE);
else
- vty_out(vty, " no emergency-imsi%s", VTY_NEWLINE);
- vty_out(vty, " %scall-waiting%s", (set->cw) ? "" : "no ", VTY_NEWLINE);
- vty_out(vty, " %sclip%s", (set->clip) ? "" : "no ", VTY_NEWLINE);
- vty_out(vty, " %sclir%s", (set->clir) ? "" : "no ", VTY_NEWLINE);
+ if (!hide_default)
+ vty_out(vty, " no emergency-imsi%s", VTY_NEWLINE);
+ if (!hide_default || set->cw)
+ vty_out(vty, " %scall-waiting%s", (set->cw) ? "" : "no ",
+ VTY_NEWLINE);
+ if (!hide_default || set->auto_answer)
+ vty_out(vty, " %sauto-answer%s",
+ (set->auto_answer) ? "" : "no ", VTY_NEWLINE);
+ if (!hide_default || set->clip)
+ vty_out(vty, " %sclip%s", (set->clip) ? "" : "no ",
+ VTY_NEWLINE);
+ if (!hide_default || set->clir)
+ vty_out(vty, " %sclir%s", (set->clir) ? "" : "no ",
+ VTY_NEWLINE);
if (set->alter_tx_power)
if (set->alter_tx_power_value)
vty_out(vty, " tx-power %d%s",
else
vty_out(vty, " tx-power full%s", VTY_NEWLINE);
else
- vty_out(vty, " tx-power auto%s", VTY_NEWLINE);
+ if (!hide_default)
+ vty_out(vty, " tx-power auto%s", VTY_NEWLINE);
if (set->alter_delay)
vty_out(vty, " simulated-delay %d%s", set->alter_delay,
VTY_NEWLINE);
else
- vty_out(vty, " no simulated-delay%s", VTY_NEWLINE);
+ if (!hide_default)
+ vty_out(vty, " no simulated-delay%s", VTY_NEWLINE);
if (set->stick)
- vty_out(vty, " stick %d%s", set->stick_arfcn,
+ vty_out(vty, " stick %d%s%s", set->stick_arfcn & 1023,
+ (set->stick_arfcn & ARFCN_PCS) ? " pcs" : "",
VTY_NEWLINE);
else
- vty_out(vty, " no stick%s", VTY_NEWLINE);
- if (set->no_lupd)
- vty_out(vty, " no location-updating%s", VTY_NEWLINE);
- else
- vty_out(vty, " location-updating%s", VTY_NEWLINE);
+ if (!hide_default)
+ vty_out(vty, " no stick%s", VTY_NEWLINE);
+ if (!hide_default || set->no_lupd)
+ vty_out(vty, " %slocation-updating%s",
+ (set->no_lupd) ? "no " : "", VTY_NEWLINE);
if (set->full_v1 || set->full_v2 || set->full_v3) {
/* mandatory anyway */
vty_out(vty, " codec full-speed%s%s",
else
vty_out(vty, " no codec half-speed%s", VTY_NEWLINE);
}
- if (llist_empty(&set->abbrev))
- vty_out(vty, " no abbrev%s", VTY_NEWLINE);
- else {
+ if (llist_empty(&set->abbrev)) {
+ if (!hide_default)
+ vty_out(vty, " no abbrev%s", VTY_NEWLINE);
+ } else {
llist_for_each_entry(abbrev, &set->abbrev, list)
vty_out(vty, " abbrev %s %s%s%s%s", abbrev->abbrev,
abbrev->number, (abbrev->name[0]) ? " " : "",
SUP_WRITE(p_gsm, "p-gsm");
SUP_WRITE(e_gsm, "e-gsm");
SUP_WRITE(r_gsm, "r-gsm");
+ SUP_WRITE(pcs, "gsm-850");
+ SUP_WRITE(gsm_480, "gsm-480");
+ SUP_WRITE(gsm_450, "gsm-450");
SUP_WRITE(dcs, "dcs");
- vty_out(vty, " class-900 %d%s", set->class_900, VTY_NEWLINE);
- vty_out(vty, " class-dcs %d%s", set->class_dcs, VTY_NEWLINE);
- switch (set->ch_cap) {
- case GSM_CAP_SDCCH:
- vty_out(vty, " channel-capability sdcch%s", VTY_NEWLINE);
- break;
- case GSM_CAP_SDCCH_TCHF:
- vty_out(vty, " channel-capability sdcch+tchf%s", VTY_NEWLINE);
- break;
- case GSM_CAP_SDCCH_TCHF_TCHH:
- vty_out(vty, " channel-capability sdcch+tchf+tchh%s",
- VTY_NEWLINE);
- break;
+ SUP_WRITE(pcs, "pcs");
+ if (sup->r_gsm || sup->e_gsm || sup->p_gsm)
+ if (!hide_default || sup->class_900 != set->class_900)
+ vty_out(vty, " class-900 %d%s", set->class_900,
+ VTY_NEWLINE);
+ if (sup->gsm_850)
+ if (!hide_default || sup->class_850 != set->class_850)
+ vty_out(vty, " class-850 %d%s", set->class_850,
+ VTY_NEWLINE);
+ if (sup->gsm_480 || sup->gsm_450)
+ if (!hide_default || sup->class_400 != set->class_400)
+ vty_out(vty, " class-400 %d%s", set->class_400,
+ VTY_NEWLINE);
+ if (sup->dcs)
+ if (!hide_default || sup->class_dcs != set->class_dcs)
+ vty_out(vty, " class-dcs %d%s", set->class_dcs,
+ VTY_NEWLINE);
+ if (sup->pcs)
+ if (!hide_default || sup->class_pcs != set->class_pcs)
+ vty_out(vty, " class-pcs %d%s", set->class_pcs,
+ VTY_NEWLINE);
+ if (!hide_default || sup->ch_cap != set->ch_cap) {
+ switch (set->ch_cap) {
+ case GSM_CAP_SDCCH:
+ vty_out(vty, " channel-capability sdcch%s",
+ VTY_NEWLINE);
+ break;
+ case GSM_CAP_SDCCH_TCHF:
+ vty_out(vty, " channel-capability sdcch+tchf%s",
+ VTY_NEWLINE);
+ break;
+ case GSM_CAP_SDCCH_TCHF_TCHH:
+ vty_out(vty, " channel-capability sdcch+tchf+tchh%s",
+ VTY_NEWLINE);
+ break;
+ }
}
SUP_WRITE(full_v1, "full-speech-v1");
SUP_WRITE(full_v2, "full-speech-v2");
SUP_WRITE(full_v3, "full-speech-v3");
SUP_WRITE(half_v1, "half-speech-v1");
SUP_WRITE(half_v3, "half-speech-v3");
- vty_out(vty, " min-rxlev %d%s", set->min_rxlev_db, VTY_NEWLINE);
- vty_out(vty, " dsc-max %d%s", set->dsc_max, VTY_NEWLINE);
+ if (!hide_default || sup->min_rxlev_db != set->min_rxlev_db)
+ vty_out(vty, " min-rxlev %d%s", set->min_rxlev_db,
+ VTY_NEWLINE);
+ if (!hide_default || sup->dsc_max != set->dsc_max)
+ vty_out(vty, " dsc-max %d%s", set->dsc_max, VTY_NEWLINE);
vty_out(vty, " exit%s", VTY_NEWLINE);
vty_out(vty, " test-sim%s", VTY_NEWLINE);
vty_out(vty, " imsi %s%s", set->test_imsi, VTY_NEWLINE);
switch (set->test_ki_type) {
case GSM_SIM_KEY_XOR:
- vty_out(vty, " ki xor %s%s", hexdump(set->test_ki, 12),
- VTY_NEWLINE);
+ vty_out(vty, " ki xor %s%s",
+ osmo_hexdump(set->test_ki, 12), VTY_NEWLINE);
break;
case GSM_SIM_KEY_COMP128:
- vty_out(vty, " ki comp128 %s%s", hexdump(set->test_ki, 16),
- VTY_NEWLINE);
+ vty_out(vty, " ki comp128 %s%s",
+ osmo_hexdump(set->test_ki, 16), VTY_NEWLINE);
break;
}
- vty_out(vty, " %sbarred-access%s", (set->test_barr) ? "" : "no ",
- VTY_NEWLINE);
- if (set->test_rplmn_valid)
- vty_out(vty, " rplmn %s %s%s",
+ if (!hide_default || set->test_barr)
+ vty_out(vty, " %sbarred-access%s",
+ (set->test_barr) ? "" : "no ", VTY_NEWLINE);
+ if (set->test_rplmn_valid) {
+ vty_out(vty, " rplmn %s %s",
gsm_print_mcc(set->test_rplmn_mcc),
- gsm_print_mnc(set->test_rplmn_mnc),
+ gsm_print_mnc(set->test_rplmn_mnc));
+ if (set->test_lac > 0x0000 && set->test_lac < 0xfffe)
+ vty_out(vty, " 0x%04x", set->test_lac);
+ if (set->test_tmsi != 0xffffffff)
+ vty_out(vty, " 0x%08x", set->test_tmsi);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ } else
+ if (!hide_default)
+ vty_out(vty, " no rplmn%s", VTY_NEWLINE);
+ if (!hide_default || set->test_always)
+ vty_out(vty, " hplmn-search %s%s",
+ (set->test_always) ? "everywhere" : "foreign-country",
VTY_NEWLINE);
- else
- vty_out(vty, " no rplmn%s", VTY_NEWLINE);
- vty_out(vty, " hplmn-search %s%s", (set->test_always) ? "everywhere"
- : "foreign-country", VTY_NEWLINE);
vty_out(vty, " exit%s", VTY_NEWLINE);
+ /* no shutdown must be written to config, because shutdown is default */
+ vty_out(vty, " %sshutdown%s", (ms->shutdown) ? "" : "no ",
+ VTY_NEWLINE);
vty_out(vty, "exit%s", VTY_NEWLINE);
vty_out(vty, "!%s", VTY_NEWLINE);
}
-static int config_write_ms(struct vty *vty)
+static int config_write(struct vty *vty)
{
struct osmocom_ms *ms;
- vty_out(vty, "gps device %s%s", gps.device, VTY_NEWLINE);
- if (gps.baud)
- vty_out(vty, "gps baudrate %d%s", gps.baud, VTY_NEWLINE);
+#ifdef _HAVE_GPSD
+ vty_out(vty, "gpsd host %s%s", g.gpsd_host, VTY_NEWLINE);
+ vty_out(vty, "gpsd port %s%s", g.gpsd_port, VTY_NEWLINE);
+#endif
+ vty_out(vty, "gps device %s%s", g.device, VTY_NEWLINE);
+ if (g.baud)
+ vty_out(vty, "gps baudrate %d%s", g.baud, VTY_NEWLINE);
else
vty_out(vty, "gps baudrate default%s", VTY_NEWLINE);
- vty_out(vty, "%sgps enable%s", (gps.enable) ? "" : "no ", VTY_NEWLINE);
+ vty_out(vty, "%sgps enable%s", (g.enable) ? "" : "no ", VTY_NEWLINE);
+ vty_out(vty, "!%s", VTY_NEWLINE);
+
+ vty_out(vty, "%shide-default%s", (hide_default) ? "": "no ",
+ VTY_NEWLINE);
vty_out(vty, "!%s", VTY_NEWLINE);
llist_for_each_entry(ms, &ms_list, entity)
- config_write_ms_single(vty, ms);
+ config_write_ms(vty, ms);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ms_show_this, cfg_ms_show_this_cmd, "show this",
+ SHOW_STR "Show config of this MS")
+{
+ struct osmocom_ms *ms = vty->index;
+
+ config_write_ms(vty, ms);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ms_layer2, cfg_ms_layer2_cmd, "layer2-socket PATH",
+ "Define socket path to connect between layer 2 and layer 1\n"
+ "Unix socket, default '/tmp/osmocom_l2'")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+
+ strncpy(set->layer2_socket_path, argv[0],
+ sizeof(set->layer2_socket_path) - 1);
+
+ vty_restart(vty, ms);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ms_sap, cfg_ms_sap_cmd, "sap-socket PATH",
+ "Define socket path to connect to SIM reader\n"
+ "Unix socket, default '/tmp/osmocom_sap'")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+ strncpy(set->sap_socket_path, argv[0],
+ sizeof(set->sap_socket_path) - 1);
+
+ vty_restart(vty, ms);
return CMD_SUCCESS;
}
return CMD_WARNING;
}
- vty_restart(vty);
+ vty_restart(vty, ms);
return CMD_SUCCESS;
}
set->imei_random = 0;
- vty_restart(vty);
+ vty_restart(vty, ms);
return CMD_SUCCESS;
}
set->imei_random = atoi(argv[0]);
- vty_restart(vty);
+ vty_restart(vty, ms);
return CMD_SUCCESS;
}
return CMD_SUCCESS;
}
+DEFUN(cfg_no_auto_answer, cfg_ms_no_auto_answer_cmd, "no auto-answer",
+ NO_STR "Disable auto-answering calls")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+
+ set->auto_answer = 0;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_auto_answer, cfg_ms_auto_answer_cmd, "auto-answer",
+ "Enable auto-answering calls")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+
+ set->auto_answer = 1;
+
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_clip, cfg_ms_clip_cmd, "clip",
"Force caller ID presentation")
{
return CMD_SUCCESS;
}
-DEFUN(cfg_ms_stick, cfg_ms_stick_cmd, "stick <0-1023>",
- "Stick to the given cell\nARFCN of the cell to stick to")
+DEFUN(cfg_ms_stick, cfg_ms_stick_cmd, "stick <0-1023> [pcs]",
+ "Stick to the given cell\nARFCN of the cell to stick to\n"
+ "Given frequency is PCS band (1900) rather than DCS band.")
{
struct osmocom_ms *ms = vty->index;
struct gsm_settings *set = &ms->settings;
+ uint16_t arfcn = atoi(argv[0]);
+ if (argc > 1) {
+ if (arfcn < 512 || arfcn > 810) {
+ vty_out(vty, "Given ARFCN not in PCS band%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ arfcn |= ARFCN_PCS;
+ }
set->stick = 1;
- set->stick_arfcn = atoi(argv[0]);
+ set->stick_arfcn = arfcn;
return CMD_SUCCESS;
}
return CMD_SUCCESS;
}
-DEFUN(cfg_abbrev, cfg_ms_abbrev_cmd, "abbrev ABBREVIATION NUMBER [name]",
+DEFUN(cfg_abbrev, cfg_ms_abbrev_cmd, "abbrev ABBREVIATION NUMBER [NAME]",
"Store given abbreviation number\n1-3 digits abbreviation\n"
"Number to store for the abbreviation "
"(Use digits '0123456789*#abc', and '+' to dial international)\n"
return CMD_SUCCESS;
}
-DEFUN(cfg_no_abbrev, cfg_ms_no_abbrev_cmd, "no abbrev [abbreviation]",
+DEFUN(cfg_no_abbrev, cfg_ms_no_abbrev_cmd, "no abbrev [ABBREVIATION]",
NO_STR "Remove given abbreviation number or all numbers\n"
"Abbreviation number to remove")
{
return CMD_WARNING; \
} \
if (restart) \
- vty_restart(vty); \
+ vty_restart(vty, ms); \
set->item = 1; \
return CMD_SUCCESS; \
}
return CMD_WARNING; \
} \
if (restart) \
- vty_restart(vty); \
+ vty_restart(vty, ms); \
+ set->item = 0; \
+ return CMD_SUCCESS; \
+}
+
+#define SET_EN(cfg, cfg_cmd, item, cmd, desc, restart) \
+DEFUN(cfg, cfg_cmd, cmd, "Enable " desc "support") \
+{ \
+ struct osmocom_ms *ms = vty->index; \
+ struct gsm_settings *set = &ms->settings; \
+ if (restart) \
+ vty_restart(vty, ms); \
+ set->item = 1; \
+ return CMD_SUCCESS; \
+}
+
+#define SET_DI(cfg, cfg_cmd, item, cmd, desc, restart) \
+DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
+{ \
+ struct osmocom_ms *ms = vty->index; \
+ struct gsm_settings *set = &ms->settings; \
+ if (restart) \
+ vty_restart(vty, ms); \
set->item = 0; \
return CMD_SUCCESS; \
}
+SET_EN(cfg_ms_sup_dtmf, cfg_ms_sup_dtmf_cmd, cc_dtmf, "dtmf", "DTMF", 0);
+SET_DI(cfg_ms_sup_no_dtmf, cfg_ms_sup_no_dtmf_cmd, cc_dtmf, "dtmf", "DTMF", 0);
SUP_EN(cfg_ms_sup_sms, cfg_ms_sup_sms_cmd, sms_ptp, "sms", "SMS", 0);
SUP_DI(cfg_ms_sup_no_sms, cfg_ms_sup_no_sms_cmd, sms_ptp, "sms", "SMS", 0);
SUP_EN(cfg_ms_sup_a5_1, cfg_ms_sup_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
"R-GSM (850)", 1);
SUP_EN(cfg_ms_sup_dcs, cfg_ms_sup_dcs_cmd, dcs, "dcs", "DCS (1800)", 0);
SUP_DI(cfg_ms_sup_no_dcs, cfg_ms_sup_no_dcs_cmd, dcs, "dcs", "DCS (1800)", 0);
+SUP_EN(cfg_ms_sup_gsm_850, cfg_ms_sup_gsm_850_cmd, gsm_850, "gsm-850",
+ "GSM 850", 0);
+SUP_DI(cfg_ms_sup_no_gsm_850, cfg_ms_sup_no_gsm_850_cmd, gsm_850, "gsm-850",
+ "GSM 850", 0);
+SUP_EN(cfg_ms_sup_pcs, cfg_ms_sup_pcs_cmd, pcs, "pcs", "PCS (1900)", 0);
+SUP_DI(cfg_ms_sup_no_pcs, cfg_ms_sup_no_pcs_cmd, pcs, "pcs", "PCS (1900)", 0);
+SUP_EN(cfg_ms_sup_gsm_480, cfg_ms_sup_gsm_480_cmd, gsm_480, "gsm-480",
+ "GSM 480", 0);
+SUP_DI(cfg_ms_sup_no_gsm_480, cfg_ms_sup_no_gsm_480_cmd, gsm_480, "gsm-480",
+ "GSM 480", 0);
+SUP_EN(cfg_ms_sup_gsm_450, cfg_ms_sup_gsm_450_cmd, gsm_450, "gsm-450",
+ "GSM 450", 0);
+SUP_DI(cfg_ms_sup_no_gsm_450, cfg_ms_sup_no_gsm_450_cmd, gsm_450, "gsm-450",
+ "GSM 450", 0);
DEFUN(cfg_ms_sup_class_900, cfg_ms_sup_class_900_cmd, "class-900 (1|2|3|4|5)",
- "Select power class for GSM 850/900\n"
+ "Select power class for GSM 900\n"
"20 Watts\n"
"8 Watts\n"
"5 Watts\n"
set->class_900 = atoi(argv[0]);
if (set->class_900 < sup->class_900 && !vty_reading)
- vty_out(vty, "You selected an higher class than supported "
+ vty_out(vty, "Note: You selected a higher class than supported "
+ " by hardware!%s", VTY_NEWLINE);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ms_sup_class_850, cfg_ms_sup_class_850_cmd, "class-850 (1|2|3|4|5)",
+ "Select power class for GSM 850\n"
+ "20 Watts\n"
+ "8 Watts\n"
+ "5 Watts\n"
+ "2 Watts\n"
+ "0.8 Watts")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+ struct gsm_support *sup = &ms->support;
+
+ set->class_850 = atoi(argv[0]);
+
+ if (set->class_850 < sup->class_850 && !vty_reading)
+ vty_out(vty, "Note: You selected a higher class than supported "
+ " by hardware!%s", VTY_NEWLINE);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ms_sup_class_400, cfg_ms_sup_class_400_cmd, "class-400 (1|2|3|4|5)",
+ "Select power class for GSM 400 (480 and 450)\n"
+ "20 Watts\n"
+ "8 Watts\n"
+ "5 Watts\n"
+ "2 Watts\n"
+ "0.8 Watts")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+ struct gsm_support *sup = &ms->support;
+
+ set->class_400 = atoi(argv[0]);
+
+ if (set->class_400 < sup->class_400 && !vty_reading)
+ vty_out(vty, "Note: You selected a higher class than supported "
" by hardware!%s", VTY_NEWLINE);
return CMD_SUCCESS;
if (((set->class_dcs + 1) & 3) < ((sup->class_dcs + 1) & 3)
&& !vty_reading)
- vty_out(vty, "You selected an higher class than supported "
+ vty_out(vty, "Note: You selected a higher class than supported "
+ " by hardware!%s", VTY_NEWLINE);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ms_sup_class_pcs, cfg_ms_sup_class_pcs_cmd, "class-pcs (1|2|3)",
+ "Select power class for PCS 1900\n"
+ "1 Watt\n"
+ "0.25 Watts\n"
+ "4 Watts")
+{
+ struct osmocom_ms *ms = vty->index;
+ struct gsm_settings *set = &ms->settings;
+ struct gsm_support *sup = &ms->support;
+
+ set->class_pcs = atoi(argv[0]);
+
+ if (((set->class_pcs + 1) & 3) < ((sup->class_pcs + 1) & 3)
+ && !vty_reading)
+ vty_out(vty, "Note: You selected a higher class than supported "
" by hardware!%s", VTY_NEWLINE);
return CMD_SUCCESS;
if (ch_cap != set->ch_cap
&& (ch_cap == GSM_CAP_SDCCH || set->ch_cap == GSM_CAP_SDCCH))
- vty_restart(vty);
+ vty_restart(vty, ms);
set->ch_cap = ch_cap;
SUP_DI(cfg_ms_sup_no_full_v3, cfg_ms_sup_no_full_v3_cmd, full_v3,
"full-speech-v3", "Full rate speech V3 (AMR)", 0);
SUP_EN(cfg_ms_sup_half_v1, cfg_ms_sup_half_v1_cmd, half_v1, "half-speech-v1",
- "Half rate speech V1 (AMR)", 0);
+ "Half rate speech V1", 0);
SUP_DI(cfg_ms_sup_no_half_v1, cfg_ms_sup_no_half_v1_cmd, half_v1,
"half-speech-v1", "Half rate speech V1", 0);
SUP_EN(cfg_ms_sup_half_v3, cfg_ms_sup_half_v3_cmd, half_v3, "half-speech-v3",
"Half rate speech V3 (AMR)", 0);
SUP_DI(cfg_ms_sup_no_half_v3, cfg_ms_sup_no_half_v3_cmd, half_v3,
- "half-speech-v3", "Half rate speech V3", 0);
+ "half-speech-v3", "Half rate speech V3 (AMR)", 0);
DEFUN(cfg_ms_sup_min_rxlev, cfg_ms_sup_min_rxlev_cmd, "min-rxlev <-110--47>",
"Set the minimum receive level to select a cell\n"
strcpy(set->test_imsi, argv[0]);
- vty_restart(vty);
+ vty_restart(vty, ms);
return CMD_SUCCESS;
}
set->test_rplmn_valid = 0;
- vty_restart(vty);
+ vty_restart(vty, ms);
return CMD_SUCCESS;
}
-DEFUN(cfg_test_rplmn, cfg_test_rplmn_cmd, "rplmn MCC MNC",
- "Set Registered PLMN\nMobile Country Code\nMobile Network Code")
+DEFUN(cfg_test_rplmn, cfg_test_rplmn_cmd, "rplmn MCC MNC [LAC] [TMSI]",
+ "Set Registered PLMN\nMobile Country Code\nMobile Network Code\n"
+ "Optionally set locatio area code\n"
+ "Optionally set current assigned TMSI")
{
struct osmocom_ms *ms = vty->index;
struct gsm_settings *set = &ms->settings;
set->test_rplmn_mcc = mcc;
set->test_rplmn_mnc = mnc;
- vty_restart(vty);
+ if (argc >= 3)
+ set->test_lac = strtoul(argv[2], NULL, 16);
+ else
+ set->test_lac = 0xfffe;
+
+ if (argc >= 4)
+ set->test_tmsi = strtoul(argv[3], NULL, 16);
+ else
+ set->test_tmsi = 0xffffffff;
+
+ vty_restart(vty, ms);
return CMD_SUCCESS;
}
break;
}
- vty_restart(vty);
+ vty_restart(vty, ms);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_no_shutdown, cfg_ms_no_shutdown_cmd, "no shutdown",
+ NO_STR "Activate and run MS")
+{
+ struct osmocom_ms *ms = vty->index, *tmp;
+ int rc;
+
+ if (ms->shutdown != 2)
+ return CMD_SUCCESS;
+
+ llist_for_each_entry(tmp, &ms_list, entity) {
+ if (tmp->shutdown == 2)
+ continue;
+ if (!strcmp(ms->settings.layer2_socket_path,
+ tmp->settings.layer2_socket_path)) {
+ vty_out(vty, "Cannot start MS '%s', because MS '%s' "
+ "use the same layer2-socket.%sPlease shutdown "
+ "MS '%s' first.%s", ms->name, tmp->name,
+ VTY_NEWLINE, tmp->name, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (!strcmp(ms->settings.sap_socket_path,
+ tmp->settings.sap_socket_path)) {
+ vty_out(vty, "Cannot start MS '%s', because MS '%s' "
+ "use the same sap-socket.%sPlease shutdown "
+ "MS '%s' first.%s", ms->name, tmp->name,
+ VTY_NEWLINE, tmp->name, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+
+ rc = mobile_init(ms);
+ if (rc < 0) {
+ vty_out(vty, "Connection to layer 1 failed!%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_shutdown, cfg_ms_shutdown_cmd, "shutdown",
+ "Shut down and deactivate MS")
+{
+ struct osmocom_ms *ms = vty->index;
+
+ if (ms->shutdown == 0)
+ mobile_exit(ms, 0);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_shutdown_force, cfg_ms_shutdown_force_cmd, "shutdown force",
+ "Shut down and deactivate MS\nDo not perform IMSI detach")
+{
+ struct osmocom_ms *ms = vty->index;
+
+ if (ms->shutdown <= 1)
+ mobile_exit(ms, 1);
+
return CMD_SUCCESS;
}
return CMD_SUCCESS;
}
+DEFUN(off, off_cmd, "off",
+ "Turn mobiles off (shutdown) and exit")
+{
+ osmo_signal_dispatch(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL);
+
+ return CMD_SUCCESS;
+}
+
#define SUP_NODE(item) \
install_element(SUPPORT_NODE, &cfg_ms_sup_item_cmd);
install_element_ve(&show_ms_cmd);
install_element_ve(&show_subscr_cmd);
install_element_ve(&show_support_cmd);
- install_element_ve(&show_states_cmd);
install_element_ve(&show_cell_cmd);
install_element_ve(&show_cell_si_cmd);
install_element_ve(&show_ba_cmd);
install_element_ve(&show_forb_plmn_cmd);
install_element_ve(&monitor_network_cmd);
install_element_ve(&no_monitor_network_cmd);
+ install_element(ENABLE_NODE, &off_cmd);
install_element(ENABLE_NODE, &sim_test_cmd);
install_element(ENABLE_NODE, &sim_reader_cmd);
install_element(ENABLE_NODE, &network_select_cmd);
install_element(ENABLE_NODE, &call_cmd);
install_element(ENABLE_NODE, &call_retr_cmd);
+ install_element(ENABLE_NODE, &call_dtmf_cmd);
+#ifdef _HAVE_GPSD
+ install_element(CONFIG_NODE, &cfg_gps_host_cmd);
+#endif
install_element(CONFIG_NODE, &cfg_gps_device_cmd);
install_element(CONFIG_NODE, &cfg_gps_baud_cmd);
install_element(CONFIG_NODE, &cfg_gps_enable_cmd);
install_element(CONFIG_NODE, &cfg_no_gps_enable_cmd);
+ install_element(CONFIG_NODE, &cfg_hide_default_cmd);
+ install_element(CONFIG_NODE, &cfg_no_hide_default_cmd);
+
install_element(CONFIG_NODE, &cfg_ms_cmd);
+ install_element(CONFIG_NODE, &cfg_ms_create_cmd);
+ install_element(CONFIG_NODE, &cfg_ms_rename_cmd);
+ install_element(CONFIG_NODE, &cfg_no_ms_cmd);
install_element(CONFIG_NODE, &ournode_end_cmd);
- install_node(&ms_node, config_write_ms);
+ install_node(&ms_node, config_write);
install_default(MS_NODE);
install_element(MS_NODE, &ournode_exit_cmd);
install_element(MS_NODE, &ournode_end_cmd);
+ install_element(MS_NODE, &cfg_ms_show_this_cmd);
+ install_element(MS_NODE, &cfg_ms_layer2_cmd);
+ install_element(MS_NODE, &cfg_ms_sap_cmd);
install_element(MS_NODE, &cfg_ms_sim_cmd);
install_element(MS_NODE, &cfg_ms_mode_cmd);
install_element(MS_NODE, &cfg_ms_imei_cmd);
install_element(MS_NODE, &cfg_ms_emerg_imsi_cmd);
install_element(MS_NODE, &cfg_ms_cw_cmd);
install_element(MS_NODE, &cfg_ms_no_cw_cmd);
+ install_element(MS_NODE, &cfg_ms_auto_answer_cmd);
+ install_element(MS_NODE, &cfg_ms_no_auto_answer_cmd);
install_element(MS_NODE, &cfg_ms_clip_cmd);
install_element(MS_NODE, &cfg_ms_clir_cmd);
install_element(MS_NODE, &cfg_ms_no_clip_cmd);
install_default(SUPPORT_NODE);
install_element(SUPPORT_NODE, &ournode_exit_cmd);
install_element(SUPPORT_NODE, &ournode_end_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_dtmf_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_dtmf_cmd);
install_element(SUPPORT_NODE, &cfg_ms_sup_sms_cmd);
install_element(SUPPORT_NODE, &cfg_ms_sup_no_sms_cmd);
install_element(SUPPORT_NODE, &cfg_ms_sup_a5_1_cmd);
install_element(SUPPORT_NODE, &cfg_ms_sup_no_r_gsm_cmd);
install_element(SUPPORT_NODE, &cfg_ms_sup_dcs_cmd);
install_element(SUPPORT_NODE, &cfg_ms_sup_no_dcs_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_gsm_850_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_gsm_850_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_pcs_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_pcs_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_gsm_480_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_gsm_480_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_gsm_450_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_no_gsm_450_cmd);
install_element(SUPPORT_NODE, &cfg_ms_sup_class_900_cmd);
install_element(SUPPORT_NODE, &cfg_ms_sup_class_dcs_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_class_850_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_class_pcs_cmd);
+ install_element(SUPPORT_NODE, &cfg_ms_sup_class_400_cmd);
install_element(SUPPORT_NODE, &cfg_ms_sup_ch_cap_cmd);
install_element(SUPPORT_NODE, &cfg_ms_sup_full_v1_cmd);
install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v1_cmd);
install_element(TESTSIM_NODE, &cfg_test_no_rplmn_cmd);
install_element(TESTSIM_NODE, &cfg_test_rplmn_cmd);
install_element(TESTSIM_NODE, &cfg_test_hplmn_cmd);
+ install_element(MS_NODE, &cfg_ms_shutdown_cmd);
+ install_element(MS_NODE, &cfg_ms_shutdown_force_cmd);
+ install_element(MS_NODE, &cfg_ms_no_shutdown_cmd);
return 0;
}