github.com/la5nta/wl2k-go@v0.11.8/transport/ardop/command.go (about)

     1  // Copyright 2015 Martin Hebnes Pedersen (LA5NTA). All rights reserved.
     2  // Use of this source code is governed by the MIT-license that can be
     3  // found in the LICENSE file.
     4  
     5  package ardop
     6  
     7  import (
     8  	"log"
     9  	"strconv"
    10  	"strings"
    11  )
    12  
    13  type command string
    14  
    15  const (
    16  	cmdPending         command = "PENDING"         // Indicates to the host application a Connect Request frame type has been detected (may not necessarily be to MYCALL or one of the MYAUX call signs). This provides an early warning to the host that a connection may be in process so it can hold any scanning activity.
    17  	cmdCancelPending   command = "CANCELPENDING"   // Indicates to the host that the prior PENDING Connect Request was not to MYCALL or one of the MYAUX call signs) This allows the Host to resume scanning.
    18  	cmdCRCFault        command = "CRCFAULT"        // Prompt to resend last frame
    19  	cmdAbort           command = "ABORT"           // Immediately aborts an ARQ Connection or a FEC Send session
    20  	cmdARQBW           command = "ARQBW"           // <200MAX|500MAX|1000MAX|2000MAX|200FORCED|500FORCED|1000FORCED|2000FORCED>
    21  	cmdARQTimeout      command = "ARQTIMEOUT"      // ARQTIMEOUT<30-240> Set/get the ARQ Timeout in seconds
    22  	cmdARQCall         command = "ARQCALL"         // <Target Callsign Repeat Count>
    23  	cmdBuffer          command = "BUFFER"          // <[int int int int int]: Buffer statistics
    24  	cmdClose           command = "CLOSE"           // Provides an orderly shutdown of all connections, release of all sound card resources and closes the Virtual TNC Program or hardware
    25  	cmdCodec           command = "CODEC"           // Start the Codec with True, Stop with False. No parameter will return the Codec state
    26  	cmdCWID            command = "CWID"            // <>[bool]: Disable/Enable the CWID option. CWID is optionally sent at the end of each ID frame.
    27  	cmdDisconnect      command = "DISCONNECT"      // Initiates a normal disconnect cycle for an ARQ connection. If not connected command is ignored.
    28  	cmdCapture         command = "CAPTURE"         // <device name>
    29  	cmdDriveLevel      command = "DRIVELEVEL"      // Set Drive level. Default = 100 (max)
    30  	cmdGridSquare      command = "GRIDSQUARE"      // <4, 6 or 8 character grid square>Sets or retrieves the 4, 6, or 8 character Maidenhead grid square (used in ID Frames) an improper grid square syntax will return a FAULT.
    31  	cmdInitialize      command = "INITIALIZE"      // Clears any pending queued values in the TNC interface. Should be sent upon initial connection and before any other parameters are sent
    32  	cmdListen          command = "LISTEN"          // Enables/disables server’s response to an ARQ connect request. Default = True. May be used to block connect requests during scanning.
    33  	cmdMyAux           command = "MYAUX"           // <aux call sign1, aux call sign2, … aux call sign10>
    34  	cmdMyCall          command = "MYCALL"          // Sets current call sign. If not a valid call generates a FAULT. Legitimate call signs include from 3 to 7 ASCII characters (A-Z, 0-9) followed by an optional “-“ and an SSID of -0 to -15 or -A to -Z. An SSID of -0 is treated as no SSID
    35  	cmdPlayback        command = "PLAYBACK"        // <device name>Sets desired sound card playback device. If no device name will reply with the current assigned playback device.
    36  	cmdProtocolMode    command = "PROTOCOLMODE"    // PROTOCOLMODE<ARQ|FEC> Sets/Gets the protocol mode. If ARQ and LISTEN above is TRUE will answer Connect requests to MYCALL or any call signs in MYAUX. If FEC will decode but not respond to any connect request.
    37  	cmdTwoToneTest     command = "TWOTONETEST"     // Send 5 second two-tone burst at the normal leader amplitude. May be used in adjusting drive level to the radio. If sent while in any state except DISC will result in a fault “not from state .....”
    38  	cmdVersion         command = "VERSION"         // Returns the name and version of the ARDOP TNC program or hardware implementation.
    39  	cmdStatus          command = "STATUS"          // ? e.g.: "STATUS CONNECT TO LA3F FAILED!"
    40  	cmdNewState        command = "NEWSTATE"        // <[State]: Sent when the state changes
    41  	cmdDisconnected    command = "DISCONNECTED"    // <[]: Signals that a connect failed. Duplicate state notification?
    42  	cmdConnected       command = "CONNECTED"       // <[string string]: Signals that an ARQ connection has been established. e.g. “CONNECTED W1ABC 500”
    43  	cmdPTT             command = "PTT"             // <[bool]: PTT active or not
    44  	cmdFault           command = "FAULT"           // <[string]: Error message
    45  	cmdBusy            command = "BUSY"            // <[bool]: Returns whether the channel is busy
    46  	cmdTarget          command = "TARGET"          // <[string]: Identifies the target call sign of the connect request. The target call will be either MYC or one of the MYAUX call signs.
    47  	cmdCaptureDevices  command = "CATPUREDEVICES"  // Returns a comma delimited list of all currently installed capture devices
    48  	cmdPlaybackDevices command = "PLAYBACKDEVICES" // Returns a comma delimited list of all currently installed playback devices.
    49  	cmdAutoBreak       command = "AUTOBREAK"       // <>[bool]: Disables/enables automatic link turnover (BREAK) by IRS when IRS has outbound data pending and receives an IDLE frame from ISS indicating its’ outbound queue is empty. Default is True.
    50  	cmdSendID          command = "SENDID"
    51  	cmdFrequency       command = "FREQUENCY"  // <Frequency in Hz>  If TNC Radio control is enabled the FREQUENCY command is sent to the Host upon a change in frequency of the radio. The frequency reported is the DIAL frequency of the radio.
    52  	cmdInputPeaks      command = "INPUTPEAKS" // Async info sent by ARDOPc
    53  
    54  	// Some of the commands that has not been implemented:
    55  	cmdBreak         command = "BREAK"
    56  	cmdBusyLock      command = "BUSYLOCK"
    57  	cmdRadioTuner    command = "RADIOTUNER"
    58  	cmdRadioAnt      command = "RADIOANT"      // Selects the radio antenna 1 or 2 for those radios that support antenna switching. If the parameter is 0 will not change the antenna setting even if the radio supports it. If sent without a parameter will return 0, 1 or 2. If RADIOCONTROL Is false or RADIOMODEL has not been set will return FAULT
    59  	cmdRadioCtrl     command = "RADIOCTRL"     // Enables/disables the radio control capability of the ARDOP_Win TNC. If sent without a parameter will return the current value of RADIOCONTROL enable.
    60  	cmdRadioCtrlBaud command = "RADIOCTRLBAUD" // <1200-115200)
    61  	cmdRadioCtrlDTR  command = "RADIOCTRLDTR"  //
    62  	cmdRadioCtrlPort command = "RADIOCTRLPORT" // COMn
    63  	cmdRadioCtrlRTS  command = "RADIOCTRLRTS"  //
    64  	cmdRadioFilter   command = "RADIOFILTER"   //
    65  	cmdRadioFreq     command = "RADIOFREQ"     //
    66  	cmdRadioComAdd   command = "RADIOCOMADD"   // 00-FF> Sets/reads the current Icom Address for radio control (Icom radios only). Values must be hex 00 through FF
    67  	cmdRadioISC      command = "RADIOISC"      // Enable/Disable Radio’s internal sound card (some radios)
    68  	cmdRadioMenu     command = "RADIOMENU"
    69  	cmdRadioMode     command = "RADIOMODE" // USB,USBD, FM>
    70  	cmdRadioModel    command = "RADIOMODEL"
    71  	cmdRadioModels   command = "RADIOMODELS"
    72  	cmdRadioPTT      command = "RADIOPTT" // CATPTT|VOX/SIGNALINK|COMn
    73  	cmdRadioPTTDTR   command = "RADIOPTTDTR"
    74  	cmdRadioPTTRTS   command = "RADIOPTTRTS"
    75  	cmdSetupMenu     command = "SETUPMENU"
    76  	cmdSquelch       command = "SQUELCH"
    77  	cmdState         command = "STATE"
    78  	cmdTrailer       command = "TRAILER"
    79  	cmdTuneRange     command = "TUNERANGE"
    80  	cmdLeader        command = "LEADER"     // LEADER<100-2000> Get/Set the leader length in ms. (Default is 160 ms). Rounded to the nearest 10 ms.
    81  	cmdDataToSend    command = "DATATOSEND" // If sent with the parameter 0 (zero) it will clear the TNC’s data to send Queue. If sent without a parameter will return the current number of data to send bytes queued.
    82  	cmdDebugLog      command = "DEBUGLOG"   // Enable/disable the debug log
    83  	cmdDisplay       command = "DISPLAY"    // Sets the Dial frequency display of the Waterfall or Spectrum display. If sent without parameters will return the current Dial frequency display. If > 100000 Display will read in MHz.
    84  	cmdTrace         command = "CMDTRACE"   // Get/Set command Trace flag to log all commands to from the TNC to the ARDOP_Win TNC debug log.
    85  	cmdFECid         command = "FECID"      // Disable/Enable ID (with optional grid square) at start of FEC transmissions
    86  	cmdFECmode       command = "FECMODE"    // FECMODE<8FSK.200.25|4FSK.200.50S|4FSK.200.50,4PSK.200.100S|4PSK.200.100|8PSK.200.100|16FSK.500.25S|16FSK.500.25|4FSK.500.100S|4FSK.500.100| 4PSK.500.100|8PSK.500.100|4PSK.500.167|8PSK.500.167|4FSK.1000.100|4PSK.1000.100|8PSK.1000.100|4PSK.1000.167|8PSK.1000.167|4FSK.2000.600S|4FSK.2000.600|4FSK.2000.100|4PSK.2000.100|8PSK.2000.100|4PSK.2000.167|8PSK.2000.167
    87  	cmdFECrepeats    command = "FECREPEATS" // <0-5> Sets the number of times a frame is repeated in FEC (multicast) mode. Higher number of repeats increases good copy probability under marginal conditions but reduces net throughput.
    88  	cmdFECsend       command = "FECSEND"    // Start/Stop FEC broadcast/multicast mode for specific FECMODE. FECSEND <False> will abort a FEC broadcast.
    89  	cmdFSKOnly       command = "FSKONLY"    // <TRUE|FALSE> If true, only FSK modulation are used for ARQ connections (ARDOPc only?)
    90  
    91  )
    92  
    93  type ctrlMsg struct {
    94  	cmd   command
    95  	value interface{}
    96  }
    97  
    98  func (msg ctrlMsg) Bool() bool {
    99  	return msg.value.(bool)
   100  }
   101  
   102  func (msg ctrlMsg) State() State {
   103  	return msg.value.(State)
   104  }
   105  
   106  func (msg ctrlMsg) String() string {
   107  	return msg.value.(string)
   108  }
   109  
   110  func (msg ctrlMsg) Int() int {
   111  	return msg.value.(int)
   112  }
   113  
   114  func parseCtrlMsg(str string) ctrlMsg {
   115  	// Work around for ARDOPc trailing space in NEWSTATE
   116  	str = strings.TrimSpace(str)
   117  
   118  	parts := strings.SplitN(str, " ", 2)
   119  	parts[0] = strings.ToUpper(parts[0])
   120  
   121  	msg := ctrlMsg{
   122  		cmd: command(parts[0]),
   123  	}
   124  
   125  	isEchoBack := len(parts) > 1 && strings.HasPrefix(strings.ToLower(parts[1]), "now ")
   126  	if isEchoBack {
   127  		parts[1] = parts[1][len("now "):]
   128  	}
   129  
   130  	switch msg.cmd {
   131  	// bool
   132  	case cmdCodec, cmdPTT, cmdBusy, cmdTwoToneTest, cmdCWID, cmdListen, cmdAutoBreak, cmdFSKOnly:
   133  		msg.value = strings.ToLower(parts[1]) == "true"
   134  
   135  	// Undocumented
   136  	case cmdInputPeaks:
   137  
   138  	// (no params)
   139  	case cmdAbort, cmdDisconnect, cmdClose, cmdDisconnected, cmdCRCFault, cmdPending, cmdCancelPending, cmdSendID:
   140  
   141  	// (echo-back only)
   142  	case cmdInitialize, cmdARQCall, cmdProtocolMode:
   143  
   144  	// State
   145  	case cmdNewState, cmdState:
   146  		msg.value = stateMap[strings.ToUpper(parts[1])]
   147  
   148  	// string
   149  	case cmdFault, cmdMyCall, cmdGridSquare, cmdCapture,
   150  		cmdPlayback, cmdVersion, cmdTarget, cmdStatus, cmdARQBW:
   151  		msg.value = parts[1]
   152  
   153  	// []string (space separated)
   154  	case cmdConnected:
   155  		msg.value = parseList(parts[1], " ")
   156  
   157  	// []string (comma separated)
   158  	case cmdCaptureDevices, cmdPlaybackDevices, cmdMyAux:
   159  		msg.value = parseList(parts[1], ",")
   160  
   161  	// int
   162  	case cmdDriveLevel, cmdBuffer, cmdARQTimeout, cmdFrequency:
   163  		i, err := strconv.Atoi(parts[1])
   164  		if err != nil {
   165  			log.Printf("Failed to parse %s value: %s", msg.cmd, err)
   166  		}
   167  		msg.value = i
   168  
   169  	default:
   170  		log.Printf("Unable to parse '%s'", str)
   171  	}
   172  
   173  	return msg
   174  }
   175  
   176  func parseList(str, sep string) []string {
   177  	parts := strings.Split(str, sep)
   178  	for i, p := range parts {
   179  		parts[i] = strings.TrimSpace(p)
   180  	}
   181  	return parts
   182  }