summaryrefslogtreecommitdiffstats
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
* src/signal.c: cosmetic: use talloc_zero()Vadim Yanitskiy2019-03-201-3/+1
| | | | Change-Id: I55c6249b0c4c82d5a181001e945ff2eca6e9ca36
* gprs_ns_sns: Properly initialize sockaddr_in in gprs_nsvc_create_ip4()Harald Welte2019-03-201-0/+2
| | | | | | | | When putting together a sockaddr_in, we must not only set the IP address and port, but also set the address family to AF_INET. And while at it, let's zero-initialize the entire 'struct sockdadr_in'. Change-Id: I1c8d8fe7f79a2ec737baa7800247269c3271983e
* socket: osmo_sock_get_name() Use "const void *" as talloc contextHarald Welte2019-03-191-1/+1
| | | | Change-Id: Ie6877277cddb0a9e049449c260afe3314ba65050
* vty/tdef_vty.c: drop redundant comparisonVadim Yanitskiy2019-03-191-1/+1
| | | | | | | | | | | | | | | The amount of arguments is already being checked a few lines before: /* If any arguments are missing, redirect to 'show' */ if (argc < 3) return show_timer(self, vty, argc, argv); so we cannot reach the expression NULL inside this statement: group_arg = argc > 0 ? argv[0] : NULL; Change-Id: Ice59d1a46c2080cd02060e3410706c502db4ce0b Fixes: CID#190873 Logically dead code (DEADCODE)
* ipa_ccm_idtag_parse*: Fix reported length valueHarald Welte2019-03-191-1/+1
| | | | | | | | | | | | | | | IPA CCM is using a somewhat weird TLV encoding scheme: * 16bit length (of tag and value) * 8bit tag * value Our existing code mapping the CCM to 'struct tlv_parse' used the plain length value without accounting for the one-byte tag. This patch ensures we only report the length of the "value" part, excluding the tag. Change-Id: I435aaa33605bd48635715a2c81aa2d231c1abf51
* rate_ctr_group_free(): guard against empty or NULL inputMax2019-03-191-1/+5
| | | | Change-Id: I859a91ee4400b3685c05971f8c66bceca6758724
* gprs_ns_sns: Use "correct" remote IP address for local IP endpointHarald Welte2019-03-161-2/+2
| | | | | | | | | | | we cannot use "nsi->nsip.remote_ip", as this address is not set when SNS is in use. We can only have a valid nsi->nsip.remote_ip if there's only a single NS-VC inside the NS Instance, as this would connect() the UDP socket to the remote IP/port, breaking any possibility to have multiple NS-VCs to different SGNS-side IP addresses. Closes: OS#3845 Change-Id: Ic094621eb01d7458063f531289d5eeadf52bf330
* gprs_ns: Don't use initial IP/port for anything but SNSHarald Welte2019-03-161-2/+55
| | | | | | | | | | | | | | | | | | | | | | | Section 6.2.1 of 3GPP TS 48.016 states: > A pre-configured endpoint shall not be used for NSE data or signalling > traffic (with the exception of Size and Configuration procedures) unless > it is configured by the SGSN using the auto-configuration procedures. However, in the current SNS implementation, the initial IP/Port over which we perform the SNS-SIZE + SNS-CONFIG are treated as one of the normal NS-VCs. Specifically, we also perform the NS-ALIVE procedure on it, which is clearly wrong. Let's explicitly create the "initial" NS-VC with data and signalling weight of 0, and ensure we never start the alive timer or send any non-SNS PDUs on this connection as long as SNS was not used to change either of the two weights to non-zero. While at it, also safeguard against processing any incoming non-SNS messages on such a all-zero-weight connection. Change-Id: I16a91a07e5914d123b2ea2f8413b94e7cd518628 Closes: OS#3844
* gprs_ns.c: Update comment: IP SNS has recently been implementedHarald Welte2019-03-161-1/+0
| | | | Change-Id: I8b98621a582a23d0483a5340b4aca7e0bc096e6d
* osmo_gsm48_classmark_a5_name(): fix 'no-cm3' labelNeels Hofmeyr2019-03-141-1/+1
| | | | Change-Id: Id84021858dfb2f7d6a7cf81ae73bd94cd47f6776
* Fix build on non-glibc systemsKarl Koscher2019-03-111-3/+8
| | | | Change-Id: Id5d577522a4889e152158f7e93ee1c99d3a21003
* gsm0808_utils: fix gsm48 multirate to S-bit converterPhilipp Maier2019-03-111-0/+10
| | | | | | | | | | | | The function gsm0808_sc_cfg_from_gsm48_mr_cfg() is used to convert a gsm48 multirate struct into a set of S-bits (S0 to S15). However, the conversion function currently does not take into account that bit S1 actually stands for four rates at once (Config-NB-Code = 1). Lets make sure that S1 is only set when the multirate configuration permits all four required rates. Change-Id: I6ad531d4e70c2252e32e2bbaca8e14a7ec6d9840 Related: SYS#4470
* gsm0808_utils: fix gsm48 multirate configuration generatorPhilipp Maier2019-03-111-21/+73
| | | | | | | | | | | | | | | | | The function gsm0808_sc_cfg_from_gsm48_mr_cfg() takes an S15 to S0 bitmask and converts that bitmask into an AMR multirate configuration struct. Unfortunately the current implementation implements 3GPP TS 28.062, Table 7.11.3.1.3-2 wrongly in some aspects. Lets fix this. - Fix wrong interpretation of the bitpatterns - 5,15K is invalid and must never be selected - Make sure that no more than 4 rates are selected in the active set - Extend unit-test Change-Id: I6fd7f4073b84093742c322752f2fd878d1071e15 Related: SYS#4470
* add gsm0808_cell_id_from_cgi(), gsm0808_cell_id_to_cgi()Neels Hofmeyr2019-03-082-0/+89
| | | | | | | | | | | | | | | | CGI to Cell ID: for example, for Paging, osmo-msc has a CGI for a subscriber and needs to send out a Cell Identifier IE. Makes sense to add this conversion here. Cell ID to CGI: for a Layer 3 Complete, a subscriber sends the current cell in the form of a Cell Identifier, which we store as a CGI, if necessary enriched with the local PLMN. Add enum with bitmask values to identify parts of a CGI, for the return value of gsm0808_cell_id_to_cgi(). Can't use enum CELL_IDENT for that, because it doesn't have a value for just a PLMN (and is not a bitmask). Change-Id: Ib9af67b100c4583342a2103669732dab2e577b04
* fsm: add osmo_fsm_inst_state_chg_keep_or_start_timer()Neels Hofmeyr2019-03-072-13/+57
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | During FSM design for osmo-msc, I noticed that the current behavior that keep_timer=true doesn't guarantee a running timer can make FSM design a bit complex, especially when using osmo_tdef for timeout definitions. A desirable keep_timer=true behavior is one that keeps the previous timer running, but starts a timer if no timer is running yet. The simplest example is: a given state repeatedly transitions back to itself, but wants to set a timeout only on first entering, avoiding to restart the timeout on re-entering. Another example is a repeated transition between two or more states, where the first time we enter this group a timeout should start, but it should not restart from scratch on every transition. When using osmo_tdef timeout definitions for this, so far separate meaningless states have to be introduced that merely set a fixed timeout. To simplify, add osmo_fsm_inst_state_chg_keep_or_start_timer(), and use this in osmo_tdef_fsm_inst_state_chg() when both keep_timer == true *and* T != 0. In tdef_test.ok, the changes show that on first entering state L, the previous T=1 is now kept with a large remaining timeout. When entering state L from O, where no timer was running, this time L's T123 is started. Change-Id: Id647511a4b18e0c4de0e66fb1f35dc9adb9177db
* represent negative T-timers as Osmocom-specific X-timersNeels Hofmeyr2019-03-062-18/+37
| | | | | | | | | | | | | | | | | | | | fi->T values are int, i.e. can be negative. Do not log them as unsigned, but define a distinct timer class "Xnnnn" for negative T values: i.e. for T == -1, print "Timeout of X1" instead of "Timeout of T4294967295". The negative T timer number space is useful to distinguish freely invented timers from proper 3GPP defined T numbers. So far I was using numbers like T993210 or T9999 for invented T, but X1, X2 etc. is a better solution. This way we can make sure to not accidentally define an invented timer number that actually collides with a proper 3GPP specified timer number that the author was not aware of at the time of writing. Add OSMO_T_FMT and OSMO_T_FMT_ARGS() macros as standardized timer number print format. Use that in fsm.c, tdef_vty.c, and adjust vty tests accordingly. Mention the two timer classes in various API docs and VTY online-docs. Change-Id: I3a59457623da9309fbbda235fe18fadd1636bff6
* api doc: tweak gsm0808_cell_id_matches_list() docNeels Hofmeyr2019-03-051-1/+2
| | | | Change-Id: Ide94558d1c31356483252b83e04b061b4ee4d3bf
* fix api doc typo for osmo_plmn_name2()Neels Hofmeyr2019-02-261-1/+1
| | | | Change-Id: Ic2652c7e4ffe1e707022168ac6c0da7c88ae7f45
* log: fsm: allow logging the timeout on state changeNeels Hofmeyr2019-02-261-2/+39
| | | | | | | | | | | | | | | | Add a flag that adds timeout info to osmo_fsm_inst state change logging. To not affect unit testing, make this an opt-in feature that is disabled by default -- mostly because osmo_fsm_inst_state_chg_keep_timer() will produce non-deterministic logging depending on timing (logs remaining time). Unit tests that don't verify log output and those that use fake time may also enable this feature. Do so in fsm_test.c. The idea is that in due course we will add osmo_fsm_log_timeouts(true) calls to all of our production applications' main() initialization. Change-Id: I089b81021a1a4ada1205261470da032b82d57872
* NS: Add support for GPRS NS IP Sub-Network-Service (SNS)Harald Welte2019-02-266-17/+1034
| | | | | | | | | | | | | | | | | | | | | | | | | | | | The NS implementation part of the Gb implementation libosmogb so far implemented a rather classic dialect of Gb, with lots of heritage to FR (Frame Relay) transports. At least since Release 6 of the NS specification, there's an IP Sub-Network Service (SNS), which * permits for dynamic configuration of IP endpoints and their NS-VCs * abandons the concept of a NSVCI on IP transport * forbids the use of RESET/BLOCK/UNBLOCK procedures on IP transport This commit introduces BSS-side IP-SNS support to libosmogb in a minimally invasive way. It adds a corresponding SNS FSM to each NS instance, and implements the new SIZE/CONFIG/ADD/DELETE/CHANGE_WEIGHT procedures very closely aligned with the spec. In order to use the SNS flavor (rather than the classic one), a BSS implementation should use gprs_ns_nsip_connect_sns() instead of the existing gprs_ns_nsip_connect(). This implementation comes with a set of TTCN-3 tests in PCU_Tests_RAW_SNS.ttcn, see Change-ID I0fe3d4579960bab0494c294ec7ab8032feed4fb2 of osmo-ttcn3-hacks.git Closes: OS#3372 Closes: OS#3617 Change-Id: I84786c3b43a8ae34ef3b3ba84b33c90042d234ea
* NS: Factor out gprs_nsvc_start_test() and use itHarald Welte2019-02-262-5/+11
| | | | | | | | | | | | This function performs sending a NS-ALIVE PDU and starting Tns-Test, let's use it in all places where we used to do that. As part of this, also fix a bug where the sendto() return value (number of bytes sent) would actually propagate up all the way to gprs_ns_rx_reset() return value, which in turn affects the test results on stdout. Change-Id: I4d303117f77fabb74bbb91887b9914a81c2a084a
* gprs_ns: Add code for SNS-SIZE and SNS-CONFIG encodingHarald Welte2019-02-263-3/+198
| | | | | | | | | | | Modern NS specifications contain a SNS (Sub Network Service) for negotiating IP/port/weight parameters of NS-over-IP links dynamically. This patch adds message encoding routines for SNS-CONFIG, SNS-SIZE and their respective acknowledgements. Related: OS#3372 Change-Id: I5c47e1c3c10deb89a7470ee2c03adfc174accc93
* LCLS: add string dump helpersMax2019-02-263-0/+45
| | | | | | | | | Add functions to dump LCLS (without GCR) and GCR. Dumping entire struct results in inconveniently long string hence the separate functions. Both use talloc functions so they expect caller to take care of providing proper allocation context and freeing memory. Change-Id: Ic3609224c8f3282d667e75f68bc20327e36eb9e6
* NS: Add missing NS Cause stringsHarald Welte2019-02-231-0/+7
| | | | | | | | When I added the definitions for the IP-SNS in commit f030b210e8c13314d361a6b721a0cbcc72935219 back in 2010, I forgot to update the string definitions in ns_cause_str[]. Let's fix that Change-Id: I419ccc482d99b01263a60aede83dacd2d9de56ab
* NS: Don't print information about FR/GRE if not enabled!Harald Welte2019-02-231-3/+4
| | | | Change-Id: I9209ee4ba5ebfc4f96b4c1d42840e1906455bae7
* select: Call log_reset_context() before calling file descriptor callbacksHarald Welte2019-02-211-0/+6
| | | | | | | | | | Make sure to clear any log context before processing the next incoming message as part of some file descriptor callback. This effectively prevents "context leaking" from processing of one message into processing of the next message as part of one iteration through the list of file descriptors here. Change-Id: I3644c7bc1a9cec5858eb0faf94efc8c3ba7f5d8d Closes: OS#3813
* gprs_ns: Add missing NSVCI IE to NS-BLOCK-ACK messageHarald Welte2019-02-191-1/+29
| | | | | | | | According to Section 9.2.4 of 3GPP TS 48.016, the NS-BLOCK-ACK PDU has a mandatory NSVCI IE which we so far were missing. Change-Id: Ie7205e99d57f1e42d941f1be2460d8c9f46aadfe Closes: OS#3808
* gprs_ns.c: cosmetic whitespace fixesHarald Welte2019-02-191-2/+2
| | | | Change-Id: Ic19f65bdc5527ad5a69d0a92320ce5f672bf4d2b
* gprs_ns: Use gprs_ns_tx_alive() instead of gprs_ns_tx_simple()Harald Welte2019-02-191-2/+2
| | | | | | If we use gprs_ns_tx_alive() we will get logging for free. Change-Id: I53d410d13540d389096c40425e1fa2eb7460b16b
* bssgp_tx_bvc_unblock(): Fix log messageHarald Welte2019-02-191-1/+1
| | | | | | | We're transmitting a BVC-UNBLOCK but the log states the opposite: BVC-BLOCK. Let's fix that. Change-Id: I70fa7336402d193513f89fcf3068b0b21925702d
* rsl: Support PDCH in rsl_chan_nr_strPau Espin Pedrol2019-02-181-0/+2
| | | | | | | | | | | | | | During log review lack of support for PDCH was spotted: scheduler.c:593 Configuring multiframe with PDCH trx=0 ts=4 rsl.c:1159 (bts=0,trx=0,ts=4,ss=0): chan_nr=UNKNOWN on TS4 type=0x00 mode=SIGNALLING rsl.c:741 (bts=0,trx=0,ts=4,pchan=TCH/F_TCH/H_PDCH as PDCH) (ss=0) PDTCH Tx CHAN ACT ACK Wireshark shows: 1100 0... = C-bits: PDCH (24) .... .100 = Time slot number (TN): 4 Change-Id: If6ed96c9eb0431eb24e2135634def61e0ea506ea
* gsm0808: comment about difference of gsm0808_create_clear_command()Harald Welte2019-02-181-1/+4
| | | | | | | | This single function has a quite different behavior than the other gsm0808_ functions in terms of how the resulting msgb l3h pointers are set. Let's document that to avoid more confusion. Change-Id: I0367760a588fc968c5a2dea46001ef1ee7965c8c
* Fix BSSMAP length generated by gsm0808_create_clear_command2()Harald Welte2019-02-181-1/+7
| | | | | | | | | | In Change-Id Id8a75e1da2d5f520064666e4ee413d1c91da6ae3 we recently introduced adding the "CSFB INDICATOR" IE to the CLEAR COMMAND, but we did so with a wrong length value. Change-Id: I4d07d25fb03ca0f89fd7b94226c54309c77a010a Closes: OS#3805 Related: OS#2778
* fix osmo_gsm48_classmark* libosmogsm.map entriesNeels Hofmeyr2019-02-151-6/+6
| | | | | | | | When the initial patch was tweaked from osmo_classmark_* to osmo_gsm48_classmark_* naming, the libosmogsm.map entries were forgotten to be changed as well. Change-Id: I53a41b5e965a529d3c146ee85102f7f1725c6014
* get_value_string(): guard against NULLNeels Hofmeyr2019-02-151-0/+3
| | | | | | | | | | | | get_value_string() conveniently prints the value number to a static buffer if it is unknown in a value_string array. Do the same if the value_string array pointer itself is NULL. If a value string array is user supplied and might be NULL, one could add a separate NULL check around it; but by making get_value_string() itself guard against NULL, another static char buffer to print the value number is avoided. Change-Id: Ie640e9258a959da8f4f9089478de993509853997
* Enable remote SIM protocol log levelMax2019-02-141-0/+5
| | | | | | | It's defined in logging.h for quite some time but is not actually enabled alongside with other internal logging categories. Change-Id: I0e7a2add6293a072752900608c8ba34cc3850f31
* gsm/gsm0480: introduce gsm0480_create_release_complete()Vadim Yanitskiy2019-02-082-0/+23
| | | | | | | | | | | | In OsmoMSC, it's required to be able to specify a particular GSM 04.07 transaction ID for GSM 04.80 Release complete message instead of the hard-coded value, that is used gsm0480_create_ussd_release_complete(). Let's finally deprecate gsm0480_create_ussd_release_complete(), and introduce a new function without USSD prefix, as this message is also used in other "structured" supplementary services. Change-Id: Ie3ac85fcef90a5e532334ba3482804d5305c88d7
* gsm0808: Add CSFB indication IE to BSSMAP CLEAR COMMANDPhilipp Maier2019-02-052-0/+17
| | | | | | | | | | | When a call that was established in a CSFB context ends the CLEAR COMMAND that is send from the BSC to the MSC should contain a CSFB indication IE, which consists of just the IE byte itsslef. This additional IE tells the BSC to include other CSFB related IEs into the RR Release message. Change-Id: Id8a75e1da2d5f520064666e4ee413d1c91da6ae3 Related: OS#3778
* add osmo_tdef API, originally adopted from osmo-bsc T_defNeels Hofmeyr2019-02-045-2/+662
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Move T_def from osmo-bsc to libosmocore as osmo_tdef. Adjust naming to be more consistent. Upgrade to first class API: - add timer grouping - add generic vty support - add mising API doc - add C test - add VTY transcript tests, also as examples for using the API From osmo_fsm_inst_state_chg() API doc, cross reference to osmo_tdef API. The root reason for moving to libosmocore is that I want to use the mgw_endpoint_fsm in osmo-msc for inter-MSC handover, and hence want to move the FSM to libosmo-mgcp-client. This FSM uses the T_def from osmo-bsc. Though the mgw_endpoint_fsm's use of T_def is minimal, I intend to use the osmo_tdef API in osmo-msc (and probably elsewhere) as well. libosmocore is the most sensible place for this. osmo_tdef provides: - a list of Tnnnn (GSM) timers with description, unit and default value. - vty UI to allow users to configure non-default timeouts. - API to tie T timers to osmo_fsm states and set them on state transitions. - a few standard units (minute, second, millisecond) as well as a custom unit (which relies on the timer's human readable description to indicate the meaning of the value). - conversion for standard units: for example, some GSM timers are defined in minutes, while our FSM definitions need timeouts in seconds. Conversion is for convenience only and can be easily avoided via the custom unit. By keeping separate osmo_tdef arrays, several groups of timers can be kept separately. The VTY tests in tests/tdef/ showcase different schemes: - tests/vty/tdef_vty_test_config_root.c: Keep several timer definitions in separately named groups: showcase the osmo_tdef_vty_groups*() API. Each timer group exists exactly once. - tests/vty/tdef_vty_test_config_subnode.c: Keep a single list of timers without separate grouping. Put this list on a specific subnode below the CONFIG_NODE. There could be several separate subnodes with timers like this, i.e. continuing from this example, sets timers could be separated by placing timers in specific config subnodes instead of using the global group name. - tests/vty/tdef_vty_test_dynamic.c: Dynamically allocate timer definitions per each new created object. Thus there can be an arbitrary number of independent timer definitions, one per allocated object. T_def was introduced during the recent osmo-bsc refactoring for inter-BSC handover, and has proven useful: - without osmo_tdef, each invocation of osmo_fsm_inst_state_chg() needs to be programmed with the right timeout value, for all code paths that invoke this state change. It is a likely source of errors to get one of them wrong. By defining a T timer exactly for an FSM state, the caller can merely invoke the state change and trust on the original state definition to apply the correct timeout. - it is helpful to have a standardized config file UI to provide user configurable timeouts, instead of inventing new VTY commands for each separate application of T timer numbers. Change-Id: Ibd6b1ed7f1bd6e1f2e0fde53352055a4468f23e5
* vty api: add vty_out_va()Neels Hofmeyr2019-02-041-12/+19
| | | | | | | | | Provide a va_list type vty_out() variant, to be able to pass on variable arguments from other function signatures to vty_out(). This will be used by Ibd6b1ed7f1bd6e1f2e0fde53352055a4468f23e5 for osmo_tdef. Change-Id: Ie6e6f11a6b794f3cb686350c1ed678e4d5bbbb75
* vty telnet: consistently never change nodes upon CTRL-CNeels Hofmeyr2019-02-041-18/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Remove any special node exiting from the VTY CTRL-C handling. From a curious VTY transcript test glitch, I noticed weird behavior by the VTY telnet shell: usually, when the user hits CTRL-C, that means to cancel the current command line and present a fresh, clean prompt. However, only on the CONFIG_NODE and CFG_LOG_NODE, a CTRL-C also exits the current node and moves up by one level. This behavior is unexplainable and makes zero sense. No other nodes exit on CTRL-C: - on the ENABLE node, a CTRL-C stays on the ENABLE_NODE and doesn't exit to the VIEW_NODE. - any sub-nodes of the CONFIG_NODE stay unchanged, e.g. 'network' or 'bts' / 'trx', etc. There is no apparent special meaning of CTRL-C on CONFIG_NODE nor CFG_LOG_NODE to justify this odd choice. Particularly, the vty transcript tests using osmo_verify_transcript_vty.py rely on sending CTRL-C to clear the command prompt, so that we can properly test sending '?' to the VTY during transcripts. In a live session, a '?' prints available options and then updates the prompt with identical command arguments. In a transcript test, that doesn't make sense, because each time the transcript writes out a new command to run. Consider e.g. a transcript test like: tdef_vty_test(config)# timer ? tea Tea time test Test timers software Typical software development cycle tdef_vty_test(config)# timer tea ? [TNNNN] T-number, optionally preceded by 't' or 'T'. To be able to issue a fresh command after '?', osmo_verify_transcript_vty.py explicitly sends a CTRL-C to clear the command buffer. Hence there we rely on predictable behavior of CTRL-C. More particularly, the upcoming osmo_tdef_vty transcript tests are apparently the first that want to test '?' behavior on the CONFIG_NODE's root level and fall on their face, because of the implicit exit that happens only there. Change-Id: I4f339ba61f1c273fa7da85caf77ba116ae2697b1
* vty: enable tab-completion for optional-multi-choice argsNeels Hofmeyr2019-02-041-1/+10
| | | | | | | | | | | | | | In cmd_complete_command_real(), detect and strip square braces from multi-choice arguments, to enable tab-completion for commands like > list cmd [(alpha|beta)] > cmd <TAB> alpha beta > cmd be<TAB> > cmd beta Change-Id: I8c304300b3633bb6e9b3457fcfa42121c8272ac0
* vty: enable optional-multi-choice syntax: [(one|two)]Neels Hofmeyr2019-02-041-3/+21
| | | | | | | | | | | | | | | | | | | | | | | | | | Since very recently we sensibly handle commands like cmd ([one]|[two]|[three]) as optional multi-choice arguments. In addition, support the more obvious syntax of cmd [(one|two|three)] Internally, the tokens are mangled to [one] [two] and [three], which is how the rest of the code detects optional args, and makes sense in terms of UI: > cmd ? [one] [two] [three] (i.e. optional arguments are always shown in braces in '?' listings) Before this patch, commands defined with a syntax like [(one|two)], would lead to an assertion (shows as "multiple") during program startup. Change-Id: I952b3c00f97e2447f2308b0ec6f5f1714692b5b2
* vty: enable optional-multi-choice syntax: ([one]|[two])Neels Hofmeyr2019-02-041-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add basic optional multi-choice argument support. The VTY detects optional arguments by square braces. > cmd ? [optional-arg] > cmd optional-arg ok > cmd ok However, within multi-choice args, these braces were so far not treated as optional: > list cmd2 ([one]|[two]|[three]) > cmd2 % Command incomplete In preparation for I952b3c00f97e2447f2308b0ec6f5f1714692b5b2 which will enable the more obvious syntax of cmd [(one|two)] for reasons of internal implementation, first support a syntax of cmd ([one]|[two]) The internal vty implementation always needs square braces around each option. There is currently no good way to prevent developers from defining braces inside multi-arguments, so it is easiest to allow and handle them: