Android Open Source - cwp-morse-mangle C W P Control Thread






From Project

Back to project page cwp-morse-mangle.

License

The source code is released under:

Copyright (C) 2012 Jussi Kivilinna <jussi.kivilinna@gmail.com> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "S...

If you think the Android project cwp-morse-mangle listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2012 Jussi Kivilinna <jussi.kivilinna@gmail.com>
 */*  w w  w.j a  v a2 s  .  c  o m*/
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

package fi_81.cwp_morse_mangle;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedByInterruptException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.ArrayDeque;

import fi_81.cwp_morse_mangle.cwp.*;
import fi_81.cwp_morse_mangle.cwp.CWInput.CWInputNotification;
import fi_81.cwp_morse_mangle.cwp.CWOutput.CWOutputNotification;
import fi_81.cwp_morse_mangle.morse.BitString;
import fi_81.cwp_morse_mangle.morse.MorseCharList;
import fi_81.cwp_morse_mangle.morse.MorseCodec;

public class CWPControlThread extends Thread {
  private static final String TAG = "CWPControlThread";

  /* Connection states */
  public static final int CONN_NO_CONFIGURATION = 0;
  public static final int CONN_RESOLVING_ADDRESS = 1;
  public static final int CONN_CREATE_CONNECTION = 2;
  public static final int CONN_CONNECTED = 3;

  /* Used to signal thread to end work */
  private AtomicBoolean isThreadKilled = new AtomicBoolean(false);

  /* ArrayDeque used for passing data to IO-thread */
  private final ArrayDeque<CWPThreadValue> msgQueue = new ArrayDeque<CWPThreadValue>();

  /* Selector for blocking on non-blocking sockets */
  private Selector selector;

  /* Initial state does not have server-details, "no configuration" */
  private int connState = CONN_NO_CONFIGURATION;

  /* Connection configuration */
  private String hostName = "";
  private int hostPort = 0;
  private int morseSpeed = 0;
  private boolean useLatencyManagement = false;

  /* Current connection setup */
  private InetSocketAddress connSockAddr;
  private long connStartTime;
  private SocketChannel connChannel;
  private SelectionKey connSelKey;
  private CWInput cwpIn;
  private CWOutput cwpOut;
  private boolean busySendingMorseMessage = false;
  private String sendMorseMessageString;

  /* Send and receive channel states */
  private boolean recvStateUp = false;
  private boolean sendStateUp = false;
  private long currFrequency = 1;
  private final StringBuffer morseMessageBits = new StringBuffer();
  private final StringBuffer recvMorseMessage = new StringBuffer();
  private final StringBuffer sendMorseMessage = new StringBuffer();

  /* Parent service */
  private CWPControlService cwpService;

  /** Service reference is needed for callbacks */
  public CWPControlThread(CWPControlService service) {
    try {
      selector = Selector.open();
    } catch (IOException e) {
      EventLog.e(
          TAG,
          "CWPControlThread(): Selector.open() failed: "
              + e.toString());
      System.exit(1);
    }

    cwpService = service;
  }

  /** Disconnect from server cleanly and setup to resolve hostname */
  private void resetServerConnection() {
    EventLog.d(TAG, "resetServerConnection()");

    /* flush pending morse */
    if (cwpIn != null)
      cwpIn.flushStaleMorseBits(inputNotify, true);

    /* cancel selection-key registration */
    if (connSelKey != null) {
      connSelKey.cancel();
      connSelKey = null;
    }

    if (connState == CONN_CONNECTED) {
      /* Should be non-null */
      if (connChannel != null) {
        try {
          connChannel.close();
        } catch (IOException e) {
          /* Do we have other option than just ignore this? */
        }
      }

      connChannel = null;
      connSockAddr = null;
      connStartTime = -1;

      connState = CONN_RESOLVING_ADDRESS;
    } else if (connState == CONN_CREATE_CONNECTION) {
      connChannel = null;
      connSockAddr = null;
      connStartTime = -1;

      connState = CONN_RESOLVING_ADDRESS;
    }

    /* Clear pending morse message */
    handleReceivedMorseMessageBuffer();

    /* Clear connection state */
    recvStateUp = false;
    sendStateUp = false;
    busySendingMorseMessage = false;
    sendMorseMessageString = null;
    sendMorseMessage.setLength(0);
    cwpIn = null;
    cwpOut = null;

    handleStateRequest();
  }

  /** Main loop of thread */
  private void run_loop() {
    try {
      /* EventLog.d(TAG, "run_loop(): %d", connState); */

      switch (connState) {
      default:
      case CONN_NO_CONFIGURATION:
        /* Wait for configuration from UI-thread. */
        sleep(Long.MAX_VALUE);
        break;

      case CONN_RESOLVING_ADDRESS:
        handleResolvingAddress();

        break;

      case CONN_CREATE_CONNECTION:
        handleCreateConnection();

        break;

      case CONN_CONNECTED:
        try {
          handleConnection();
        } catch (IOException e) {
          EventLog.w(TAG,
              "Server connection IOException: " + e.toString());

          /* IOException, connection trouble, reset connection */
          resetServerConnection();
        }

        break;
      }
    } catch (ClosedChannelException e) {
      /* this is does not happen as selector is closed after run_loop() */
    } catch (InterruptedException ie) {
      /* woke from sleep */
    }

    /* Thread is being killed? */
    if (isThreadKilled.get())
      return;

    /*
     * Each connection state handler might be sleeping and have sleep
     * interrupted by messages from UI-thread.
     */
    handleMessageQueue();
  }

  private void handleResolvingAddress() throws InterruptedException {
    /* Resolve IP-address for hostname */
    try {
      connSockAddr = new InetSocketAddress(
          InetAddress.getByName(hostName), hostPort);

      /* TODO: notify UI-thread about successful connection */

      connState = CONN_CREATE_CONNECTION;
    } catch (UnknownHostException e) {
      /* Invalid hostname, cannot be resolved */

      /* Wait some time before retrying resolving address */
      sleep(5000);
    }
  }

  private void handleCreateConnection() throws InterruptedException,
      ClosedChannelException {
    connChannel = null;

    try {
      /* open socket and store connection time */
      connChannel = SocketChannel.open(connSockAddr);
      connStartTime = System.currentTimeMillis();

      /* make channel non-blocking */
      connChannel.configureBlocking(false);

      /* adjust socket for low-latency */
      connChannel.socket().setTcpNoDelay(true);

      /* in connected state now */
      connState = CONN_CONNECTED;
    } catch (SocketException se) {
      /* clean up */
      if (connChannel != null) {
        try {
          connChannel.close();
        } catch (IOException e) {
        }
      }

      /* Try resolve address first */
      connState = CONN_RESOLVING_ADDRESS;

      /* Short sleep to avoid busy loop */
      sleep(2000);
      return;
    } catch (ClosedByInterruptException cbie) {
      /*
       * Interrupted in SocketChannel.open() blocking I/O. Channel has
       * been closed, retry connection on next loop.
       */
      connState = CONN_CREATE_CONNECTION;
      throw new InterruptedException();
    } catch (IOException ioe) {
      /* IO error, need to reset connection */
      if (connChannel != null) {
        try {
          connChannel.close();
        } catch (IOException e) {
        }
      }

      /*
       * IOException is hard error, maybe internet connection was lost. Go
       * back to resolving address.
       */
      connState = CONN_RESOLVING_ADDRESS;

      /* Short sleep to avoid busy loop */
      sleep(200);
      return;
    }

    /* Register read-channel to selector */
    connSelKey = connChannel.register(selector, SelectionKey.OP_READ);

    /* Connection has been created, initialize other components */
    if (useLatencyManagement) {
      /* Set maximum latency management buffer length to 10 sec */
      cwpIn = new CWInput(10000 /* ms */, connStartTime);
    } else
      cwpIn = new CWInput();

    cwpOut = new CWOutput(connStartTime);

    /* set frequency if not default */
    if (currFrequency != 1)
      cwpOut.sendFrequenceChange(currFrequency);
  }

  /**
   * Handle sending and receiving data from CWP server
   * 
   * @throws ClosedChannelException
   */
  private void handleConnection() throws IOException {
    long timeToNextWork;
    int numReadyChannels, interestSet;

    /* Always interested in reading */
    interestSet = SelectionKey.OP_READ;

    /* CWP output handling */
    cwpOut.processOutput(outputNotify);

    /* Check if need to register write-channel to selector */
    if (cwpOut.getOutputBuffer().remaining() > 0) {
      /* Set interest on writing too */
      interestSet |= SelectionKey.OP_WRITE;
    }

    /* Update interest set for key */
    connSelKey.interestOps(interestSet);

    /* Get time to next CWOutput or CWInput work */
    timeToNextWork = Math.min(cwpOut.timeToNextWork(),
        cwpIn.timeToNextWork());

    /* Wait for input */
    if (timeToNextWork == 0)
      numReadyChannels = selector.selectNow();
    else {
      /*
       * Workaround Java or Darvik bug, cannot handle Long.MAX_VALUE.
       * Throws SocketException.
       */
      if (timeToNextWork > Integer.MAX_VALUE)
        timeToNextWork = Integer.MAX_VALUE;

      numReadyChannels = selector.select(timeToNextWork);
    }

    /* Receive and send data */
    if (numReadyChannels > 0) {
      handleNonBlockingNetworkIO();

      if (busySendingMorseMessage && cwpOut.queueSize() == 0
          && cwpOut.getOutputBuffer().remaining() == 0) {
        /* Sending morse message completed */
        busySendingMorseMessage = false;
        sendMorseMessageString = null;
        cwpService.notifyMorseMessageSendingState(true, null);
      }
    }

    /* CWP input handling */
    cwpIn.processInput(inputNotify);
  }

  private void handleNonBlockingNetworkIO() throws IOException {
    ByteBuffer inBuf = cwpIn.getInBuffer();
    ByteBuffer outBuf = cwpOut.getOutputBuffer();
    Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator();
    int bytesCopied;

    /* Iterate active selection keys */
    while (keyIter.hasNext()) {
      SelectionKey key = keyIter.next();

      /* Input reader */
      if (key.isValid() && key.isReadable()) {
        bytesCopied = connChannel.read(inBuf);

        if (bytesCopied > 0)
          EventLog.startProfRecv(System.currentTimeMillis());
      }

      /* Output writer */
      if (key.isValid() && key.isWritable()) {
        bytesCopied = connChannel.write(outBuf);

        if (bytesCopied > 0)
          EventLog.endProfSend(System.currentTimeMillis());
      }

      keyIter.remove();
    }
  }

  /** Handle messages from UI-thread */
  private void handleMessageQueue() {
    CWPThreadValue value;

    while ((value = queuePop(msgQueue)) != null) {
      switch (value.type) {
      case CWPThreadValue.TYPE_CONFIGURATION:
        handleNewConfiguration(value.getHostName(),
            value.getHostPort(), value.getMorseSpeed(),
            value.getUseLatencyManagement());
        break;
      case CWPThreadValue.TYPE_STATE_CHANGE:
        handleNewSendingState(value.isStateUp());
        break;
      case CWPThreadValue.TYPE_FREQ_CHANGE:
        handleNewFrequency(value.getFrequency());
        break;
      case CWPThreadValue.TYPE_MORSE_MESSAGE:
        handleNewMorseMessage(value.getMorseMessage());
        break;
      case CWPThreadValue.TYPE_STATE_REQUEST:
        handleStateRequest();
        break;
      case CWPThreadValue.TYPE_CLEAR_MESSAGES:
        recvMorseMessage.setLength(0);
        cwpService.notifyMorseUpdates("");
        break;
      }
    }
  }

  private void handleStateRequest() {
    cwpService.notifyFrequencyChange(currFrequency);
    cwpService.notifyStateChange(recvStateUp, sendStateUp);
    cwpService.notifyMorseUpdates(recvMorseMessage.toString());
    cwpService.notifyMorseMessageSendingState(!busySendingMorseMessage,
        sendMorseMessageString);
  }

  private void handleNewMorseMessage(String morse) {
    if (connState == CONN_CONNECTED && cwpOut != null) {
      /* Caller should make sure this does not happen */
      if (busySendingMorseMessage)
        return;

      busySendingMorseMessage = true;
      sendMorseMessageString = morse;

      /* Convert message to morse-code BitString */
      sendMorseMessage.setLength(0);
      sendMorseMessage.append(MorseCharList.SPECIAL_START_OF_MESSAGE);
      sendMorseMessage.append(morse);
      sendMorseMessage.append(MorseCharList.SPECIAL_END_OF_CONTACT);

      BitString morseBits = MorseCodec
          .encodeMessageToMorse(sendMorseMessage);

      /* Fill in morse message */
      cwpOut.sendDown();
      cwpOut.sendMorseCode(morseBits);

      /* Report state to activity */
      cwpService.notifyMorseMessageSendingState(false,
          sendMorseMessageString);
    } else {
      /* Just complete morse message sending when not connected */
      sendMorseMessageString = null;
      cwpService.notifyMorseMessageSendingState(true, null);
    }
  }

  private void handleNewFrequency(long frequency) {
    if (currFrequency != frequency) {
      currFrequency = frequency;

      if (connState == CONN_CONNECTED && cwpOut != null)
        cwpOut.sendFrequenceChange(currFrequency);
    }
  }

  private void handleNewSendingState(boolean stateUp) {
    if (busySendingMorseMessage)
      return;

    if (connState == CONN_CONNECTED && cwpOut != null) {
      if (stateUp)
        cwpOut.sendUp();
      else
        cwpOut.sendDown();
    }
  }

  private void handleNewConfiguration(String hostName, int hostPort,
      int morseSpeed, boolean useLatencyManagement) {
    /* Enforce valid range of port */
    if (hostPort < 0)
      hostPort = 0;
    else if (hostPort > 0xffff)
      hostPort = 0xffff;

    /* No configuration, fill in values and change connection state */
    if (connState == CONN_NO_CONFIGURATION) {
      this.hostName = hostName;
      this.hostPort = hostPort;
      this.morseSpeed = morseSpeed;
      this.useLatencyManagement = useLatencyManagement;

      CWStateChangeQueueFromMorseCode.setSignalWidth(morseSpeed);
      CWStateChangeQueueFromMorseCode.setSignalJitter(Integer.MAX_VALUE,
          0.0);

      connState = CONN_RESOLVING_ADDRESS;
      return;
    }

    if (this.morseSpeed != morseSpeed) {
      /* Set new morse speed */
      CWStateChangeQueueFromMorseCode.setSignalWidth(morseSpeed);

      this.morseSpeed = morseSpeed;
    }

    if (this.hostName.compareTo(hostName) != 0 || this.hostPort != hostPort
        || this.useLatencyManagement != useLatencyManagement) {
      /* Server setup changed, trigger reconnection */
      this.hostName = hostName;
      this.hostPort = hostPort;
      this.useLatencyManagement = useLatencyManagement;

      /* restart from resolving server address */
      resetServerConnection();
    }
  }

  /** Decode received morse bits to message string and pass to UI-thread */
  private void handleReceivedMorseMessageBuffer() {
    /* Nothing to process? */
    if (morseMessageBits.length() == 0)
      return;

    morseMessageBits.append(BitString.newZeros(3));
    String message = MorseCodec.decodeMorseToMessage(BitString
        .newBits(morseMessageBits.toString()));

    /* No message? */
    if (message == null || message.length() == 0)
      return;

    /* Fill to main message buffer */
    recvMorseMessage.append(' ');
    for (char ch : message.toCharArray()) {
      /* Handle SOS specially */
      if (ch == MorseCharList.SPECIAL_SOS) {
        recvMorseMessage.append("SOS!");
        continue;
      }

      /* Fill end-message control codes with space */
      if (ch == MorseCharList.SPECIAL_END_OF_CONTACT
          || ch == MorseCharList.SPECIAL_END_OF_MESSAGE
          || ch == MorseCharList.SPECIAL_STOP_MESSAGE)
        ch = ' ';

      /* Exclude other control codes */
      if (Character.isUpperCase(ch))
        continue;

      recvMorseMessage.append(ch);
    }

    /* Send updated morse-message string to UI */
    cwpService.notifyMorseUpdates(recvMorseMessage.toString());

    morseMessageBits.setLength(0);
  }

  /** Handle callbacks from CWInput */
  private final CWInputNotification inputNotify = new CWInputNotification() {
    public void frequencyChange(long newFreq) {
      /* flush pending morse */
      cwpIn.flushStaleMorseBits(inputNotify, true);

      /* Clear pending morse message */
      handleReceivedMorseMessageBuffer();

      cwpService.notifyFrequencyChange(newFreq);
    }

    public void stateChange(byte newState, int value) {
      boolean isUpState = newState == CWave.TYPE_UP;

      /* Report state change */
      if (recvStateUp != isUpState) {
        recvStateUp = isUpState;

        cwpService.notifyStateChange(recvStateUp, sendStateUp);
      }
    }

    public void morseMessage(BitString morseBits) {
      /* Gather all message bits */
      morseMessageBits.append(morseBits);

      /*
       * Message is ended either with endSequence (our internal
       * implementation specific code) or by endContact (by sender)
       */
      if (BitString.stringBufferEndWithBits(morseMessageBits,
          MorseCodec.endSequence)
          || BitString.stringBufferEndWithBits(morseMessageBits,
              MorseCodec.endContact)) {
        handleReceivedMorseMessageBuffer();
      }
    }
  };

  /** Handle callbacks from CWOutput */
  private final CWOutputNotification outputNotify = new CWOutputNotification() {
    public void frequencyChange(long newFreq) {
      cwpService.notifyFrequencyChange(newFreq);
    }

    public void stateChange(byte newState, int value) {
      boolean isUpState = newState == CWave.TYPE_UP;

      /* Report state change */
      if (sendStateUp != isUpState) {
        sendStateUp = isUpState;

        cwpService.notifyStateChange(recvStateUp, sendStateUp);
      }
    }
  };

  @Override
  public void run() {
    while (!isThreadKilled.get())
      run_loop();

    /*
     * Parent has killed CWP thread, do clean up
     */

    cwpIn = null;
    cwpOut = null;

    resetServerConnection();

    msgQueue.clear();

    try {
      selector.close();
    } catch (IOException e) {
      EventLog.w(
          TAG,
          "run()/cleanup: selector.close() exception: "
              + e.toString());
    }
  }

  /** Signal and wait thread to quit work */
  public void endWorkAndJoin() {
    isThreadKilled.set(true);
    interrupt();

    try {
      join();
    } catch (InterruptedException ie) {
      /* UI-thread interrupted from wait */
      EventLog.w(TAG,
          "endWorkAndJoin(): joining ioThread failed with exception: "
              + ie.toString());
    }
  }

  /** Set up new configuration for server */
  public void setNewConfiguration(String hostName, int hostPort,
      int morseSpeed, boolean useLatencyManagement) {
    /* Push new configuration as message to IO-thread */
    queuePush(msgQueue, CWPThreadValue.buildConfiguration(hostName,
        hostPort, morseSpeed, useLatencyManagement));

    /* signal IO-thread of new message */
    interrupt();
  }

  /** Set new frequency */
  public void setFrequency(long freq) {
    /* Push new frequency to IO-thread */
    queuePush(msgQueue, CWPThreadValue.buildFreqChange(freq));

    /* signal IO-thread of new message */
    interrupt();
  }

  /** Set sending state */
  public void setSendingState(boolean setUpState) {
    /* Push new frequency to IO-thread */
    queuePush(msgQueue, CWPThreadValue.buildStateChange(setUpState));

    /* signal IO-thread of new message */
    interrupt();
  }

  /** Set to send morse message */
  public void sendMorseMessage(String morse) {
    /* Push new frequency to IO-thread */
    queuePush(msgQueue, CWPThreadValue.buildMorseMessage(morse));

    /* signal IO-thread of new message */
    interrupt();
  }

  /** Request current state from IO-thread */
  public void requestCurrentState() {
    /* Push new frequency to IO-thread */
    queuePush(msgQueue, CWPThreadValue.buildStateRequest());

    /* signal IO-thread of new message */
    interrupt();
  }

  /** Request to clear received morse messages */
  public void requestClearMessages() {
    /* Push new frequency to IO-thread */
    queuePush(msgQueue, CWPThreadValue.buildClearMessages());

    /* signal IO-thread of new message */
    interrupt();
  }

  private static void queuePush(ArrayDeque<CWPThreadValue> queue,
      CWPThreadValue value) {
    synchronized (queue) {
      queue.push(value);
    }
  }

  private static CWPThreadValue queuePop(ArrayDeque<CWPThreadValue> queue) {
    try {
      synchronized (queue) {
        if (queue.size() == 0)
          return null;

        return queue.pop();
      }
    } catch (NoSuchElementException NSEE) {
      /* empty queue */
      return null;
    }
  }

  /** Class for passing messages from UI-thread to IO-thread */
  private static class CWPThreadValue {
    protected static final int TYPE_CONFIGURATION = 0;
    protected static final int TYPE_STATE_CHANGE = 1;
    protected static final int TYPE_FREQ_CHANGE = 2;
    protected static final int TYPE_MORSE_MESSAGE = 3;
    protected static final int TYPE_STATE_REQUEST = 4;
    protected static final int TYPE_CLEAR_MESSAGES = 5;

    protected int type;
    protected long argLong0;
    protected int argInt0;
    protected boolean argBool0;
    protected Object argObj0;

    protected static CWPThreadValue buildConfiguration(String hostName,
        int hostPort, int morseSpeed, boolean useLatencyManagement) {
      CWPThreadValue value = new CWPThreadValue();

      value.type = TYPE_CONFIGURATION;
      value.argObj0 = hostName;
      value.argLong0 = hostPort;
      value.argInt0 = morseSpeed;
      value.argBool0 = useLatencyManagement;

      return value;
    }

    protected static CWPThreadValue buildStateChange(boolean isStateUp) {
      CWPThreadValue value = new CWPThreadValue();

      value.type = TYPE_STATE_CHANGE;
      value.argObj0 = null;
      value.argLong0 = isStateUp ? 1 : 0;
      value.argInt0 = 0;
      value.argBool0 = false;

      return value;
    }

    protected static CWPThreadValue buildFreqChange(long freq) {
      CWPThreadValue value = new CWPThreadValue();

      value.type = TYPE_FREQ_CHANGE;
      value.argObj0 = null;
      value.argLong0 = freq;
      value.argInt0 = 0;
      value.argBool0 = false;

      return value;
    }

    protected static CWPThreadValue buildMorseMessage(String morse) {
      CWPThreadValue value = new CWPThreadValue();

      value.type = TYPE_MORSE_MESSAGE;
      value.argObj0 = morse;
      value.argLong0 = 0;
      value.argInt0 = 0;
      value.argBool0 = false;

      return value;
    }

    protected static CWPThreadValue buildStateRequest() {
      CWPThreadValue value = new CWPThreadValue();

      value.type = TYPE_STATE_REQUEST;
      value.argObj0 = null;
      value.argLong0 = 0;
      value.argInt0 = 0;
      value.argBool0 = false;

      return value;
    }

    protected static CWPThreadValue buildClearMessages() {
      CWPThreadValue value = new CWPThreadValue();

      value.type = TYPE_CLEAR_MESSAGES;
      value.argObj0 = null;
      value.argLong0 = 0;
      value.argInt0 = 0;
      value.argBool0 = false;

      return value;
    }

    /*
     * Values for TYPE_CONFIGURATION
     */
    protected String getHostName() {
      return (String) argObj0;
    }

    protected int getHostPort() {
      return (int) argLong0;
    }

    protected int getMorseSpeed() {
      return argInt0;
    }

    protected boolean getUseLatencyManagement() {
      return argBool0;
    }

    /*
     * Values for TYPE_STATE_CHANGE
     */
    protected boolean isStateUp() {
      return argLong0 == 1;
    }

    /*
     * Values for TYPE_FREQUENCY_CHANGE
     */
    protected long getFrequency() {
      return argLong0;
    }

    /*
     * Values for TYPE_MORSE_MESSAGE
     */
    protected String getMorseMessage() {
      return (String) argObj0;
    }
  }
}




Java Source Code List

fi_81.cwp_morse_mangle.CWPControlService.java
fi_81.cwp_morse_mangle.CWPControlThread.java
fi_81.cwp_morse_mangle.DefaultSettings.java
fi_81.cwp_morse_mangle.EventLog.java
fi_81.cwp_morse_mangle.MainActivity.java
fi_81.cwp_morse_mangle.MainSettingsActivity.java
fi_81.cwp_morse_mangle.SinAudioLoop.java
fi_81.cwp_morse_mangle.cwp.CWFrequencyChange.java
fi_81.cwp_morse_mangle.cwp.CWInputQueue.java
fi_81.cwp_morse_mangle.cwp.CWInput.java
fi_81.cwp_morse_mangle.cwp.CWOutput.java
fi_81.cwp_morse_mangle.cwp.CWStateChangeQueueFromMorseCode.java
fi_81.cwp_morse_mangle.cwp.CWStateChange.java
fi_81.cwp_morse_mangle.cwp.CWaveQueueToMorseCode.java
fi_81.cwp_morse_mangle.cwp.CWave.java
fi_81.cwp_morse_mangle.morse.BitString.java
fi_81.cwp_morse_mangle.morse.MorseCharList.java
fi_81.cwp_morse_mangle.morse.MorseChar.java
fi_81.cwp_morse_mangle.morse.MorseCodec.java