示例#1
0
  public void run() { // start a new thread
    // this thread has one task.  It repeatedly reads from the input pipe
    // and writes modified data to the output pipe.  This is the heart
    // of the command station simulation.
    if (log.isDebugEnabled()) {
      log.debug("Simulator Thread Started");
    }

    Random rgen = new Random();

    ConnectionStatus.instance()
        .setConnectionState(this.getCurrentPortName(), ConnectionStatus.CONNECTION_UP);
    for (; ; ) {
      DCCppMessage m = readMessage();
      if (log.isDebugEnabled()) {
        log.debug("Simulator Thread received message " + m.toString());
      }
      DCCppReply r = generateReply(m);
      // If generateReply() returns null, do nothing. No reply to send.
      if (r != null) {
        writeReply(r);
        if (log.isDebugEnabled()) {
          log.debug("Simulator Thread sent Reply" + r.toString());
        }
      }

      // Once every SENSOR_MSG_RATE loops, generate a random Sensor message.
      int rand = rgen.nextInt(SENSOR_MSG_RATE);
      if (rand == 1) {
        generateRandomSensorReply();
      }
    }
  }
示例#2
0
 private void writeReply(DCCppReply r) {
   int i;
   int len = r.getLength(); // opCode+Nbytes+ECC
   // If r == null, there is no reply to be sent.
   try {
     outpipe.writeByte((byte) '<');
     for (i = 0; i < len; i++) {
       outpipe.writeByte((byte) r.getElement(i));
     }
     outpipe.writeByte((byte) '>');
   } catch (java.io.IOException ex) {
     ConnectionStatus.instance()
         .setConnectionState(this.getCurrentPortName(), ConnectionStatus.CONNECTION_DOWN);
   }
 }
示例#3
0
  private void generateRandomSensorReply() {
    // Pick a random sensor number between 0 and 10;
    Random sNumGenerator = new Random();
    int sensorNum = sNumGenerator.nextInt(10); // Generate a random sensor number between 0 and 9
    Random valueGenerator = new Random();
    int value = valueGenerator.nextInt(2); // Generate state value betweeon 0 and 1

    String reply = new String((value == 1 ? "Q " : "q ") + Integer.toString(sensorNum));

    DCCppReply r = DCCppReply.parseDCCppReply(reply);
    writeReply(r);
    if (log.isDebugEnabled()) {
      log.debug("Simulator Thread sent Reply" + r.toString());
    }
  }
示例#4
0
  private void generateReadCSStatusReply() {
    /*
    String s = new String("<p" + (TrackPowerState ? "1" : "0") + ">");
    DCCppReply r = new DCCppReply(s);
    writeReply(r);
    if (log.isDebugEnabled()) {
        log.debug("Simulator Thread sent Reply" + r.toString());
    }
    */

    DCCppReply r =
        DCCppReply.parseDCCppReply(
            "iDCC++ BASE STATION FOR ARDUINO MEGA / ARDUINO MOTOR SHIELD: BUILD 05 Nov 2015 00:09:57");
    writeReply(r);
    if (log.isDebugEnabled()) {
      log.debug("Simulator Thread sent Reply" + r.toString());
    }

    // Generate the other messages too...
  }
示例#5
0
  // generateReply is the heart of the simulation.  It translates an
  // incoming DCCppMessage into an outgoing DCCppReply.
  @SuppressWarnings("fallthrough")
  private DCCppReply generateReply(DCCppMessage msg) {
    String s, r;
    Pattern p;
    Matcher m;
    DCCppReply reply = null;

    log.debug("Generate Reply to message type {} string = {}", msg.getElement(0), msg.toString());

    switch (msg.getElement(0)) {
      case DCCppConstants.THROTTLE_CMD:
        log.debug("THROTTLE_CMD detected");
        s = msg.toString();
        try {
          p = Pattern.compile(DCCppConstants.THROTTLE_CMD_REGEX);
          m = p.matcher(s);
          if (!m.matches()) {
            log.error("Malformed Throttle Command: {}", s);
            return (null);
          }
          r = "T " + m.group(1) + " " + m.group(3) + " " + m.group(4);
          reply = DCCppReply.parseDCCppReply(r);
          log.debug("Reply generated = {}", reply.toString());
        } catch (PatternSyntaxException e) {
          log.error("Malformed pattern syntax! ");
          return (null);
        } catch (IllegalStateException e) {
          log.error("Group called before match operation executed string= " + s);
          return (null);
        } catch (IndexOutOfBoundsException e) {
          log.error("Index out of bounds string= " + s);
          return (null);
        }
        break;

      case DCCppConstants.TURNOUT_CMD:
        if (msg.isTurnoutAddMessage()) {
          log.debug("Add Turnout Message");
          r = "O";
        } else if (msg.isTurnoutDeleteMessage()) {
          log.debug("Delete Turnout Message");
          r = "O";
        } else if (msg.isListTurnoutsMessage()) {
          log.debug("List Turnouts Message");
          r = "H 1 27 3 1";
        } else {
          log.debug("TURNOUT_CMD detected");
          r = "H" + msg.getTOIDString() + " " + msg.getTOStateString();
        }
        reply = DCCppReply.parseDCCppReply(r);
        log.debug("Reply generated = {}", reply.toString());
        break;

      case DCCppConstants.SENSOR_CMD:
        if (msg.isSensorAddMessage()) {
          log.debug("SENSOR_CMD Add detected");
          s = msg.toString();
          r = "O"; // TODO: Randomize?
        } else if (msg.isSensorDeleteMessage()) {
          log.debug("SENSOR_CMD Delete detected");
          s = msg.toString();
          r = "O"; // TODO: Randomize?
        } else if (msg.isListSensorsMessage()) {
          r = "Q 1 4 1"; // TODO: DO this for real.
        } else {
          log.debug("Invalid SENSOR_CMD detected");
          r = "X";
        }
        reply = DCCppReply.parseDCCppReply(r);
        log.debug("Reply generated = {}", reply.toString());
        break;

      case DCCppConstants.PROG_WRITE_CV_BYTE:
        log.debug("PROG_WRITE_CV_BYTE detected");
        s = msg.toString();
        try {
          p = Pattern.compile(DCCppConstants.PROG_WRITE_BYTE_REGEX);
          m = p.matcher(s);
          if (!m.matches()) {
            log.error("Malformed ProgWriteCVByte Command: {}", s);
            return (null);
          }
          r = "r " + m.group(3) + " " + m.group(4) + " " + m.group(2);
          CVs[Integer.parseInt(m.group(1))] = Integer.parseInt(m.group(2));
          reply = DCCppReply.parseDCCppReply(r);
          log.debug("Reply generated = {}", reply.toString());
        } catch (PatternSyntaxException e) {
          log.error("Malformed pattern syntax! ");
          return (null);
        } catch (IllegalStateException e) {
          log.error("Group called before match operation executed string= " + s);
          return (null);
        } catch (IndexOutOfBoundsException e) {
          log.error("Index out of bounds string= " + s);
          return (null);
        }
        break;

      case DCCppConstants.PROG_WRITE_CV_BIT:
        log.debug("PROG_WRITE_CV_BIT detected");
        s = msg.toString();
        try {
          p = Pattern.compile(DCCppConstants.PROG_WRITE_BIT_REGEX);
          m = p.matcher(s);
          if (!m.matches()) {
            log.error("Malformed ProgWriteCVBit Command: {}", s);
            return (null);
          }
          r = "r " + m.group(4) + " " + m.group(5) + " " + m.group(3);
          int idx = Integer.parseInt(m.group(1));
          int bit = Integer.parseInt(m.group(2));
          int v = Integer.parseInt(m.group(3));
          if (v == 1) CVs[idx] = CVs[idx] | (0x0001 << bit);
          else CVs[idx] = CVs[idx] & ~(0x0001 << bit);
          reply = DCCppReply.parseDCCppReply(r);
          log.debug("Reply generated = {}", reply.toString());
        } catch (PatternSyntaxException e) {
          log.error("Malformed pattern syntax! ");
          return (null);
        } catch (IllegalStateException e) {
          log.error("Group called before match operation executed string= " + s);
          return (null);
        } catch (IndexOutOfBoundsException e) {
          log.error("Index out of bounds string= " + s);
          return (null);
        }
        break;

      case DCCppConstants.PROG_READ_CV:
        log.debug("PROG_READ_CV detected");
        s = msg.toString();
        try {
          p = Pattern.compile(DCCppConstants.PROG_READ_REGEX);
          m = p.matcher(s);
          if (!m.matches()) {
            log.error("Malformed PROG_READ_CV Command: {}", s);
            return (null);
          }
          // TODO: Work Magic Here to retrieve stored value.
          int cv = CVs[Integer.parseInt(m.group(1))];
          r = "r " + m.group(2) + " " + m.group(3) + " " + Integer.toString(cv);
          reply = DCCppReply.parseDCCppReply(r);
          log.debug("Reply generated = {}", reply.toString());
        } catch (PatternSyntaxException e) {
          log.error("Malformed pattern syntax! ");
          return (null);
        } catch (IllegalStateException e) {
          log.error("Group called before match operation executed string= " + s);
          return (null);
        } catch (IndexOutOfBoundsException e) {
          log.error("Index out of bounds string= " + s);
          return (null);
        }
        break;

      case DCCppConstants.TRACK_POWER_ON:
        log.debug("TRACK_POWER_ON detected");
        TrackPowerState = true;
        reply = DCCppReply.parseDCCppReply("p1");
        log.debug("Reply generated = {}", reply.toString());
        break;

      case DCCppConstants.TRACK_POWER_OFF:
        log.debug("TRACK_POWER_OFF detected");
        TrackPowerState = false;
        reply = DCCppReply.parseDCCppReply("p0");
        log.debug("Reply generated = {}", reply.toString());
        break;

      case DCCppConstants.READ_TRACK_CURRENT:
        log.debug("READ_TRACK_CURRENT detected");
        int randint = 480 + rgen.nextInt(64);
        reply =
            DCCppReply.parseDCCppReply("a " + (TrackPowerState ? Integer.toString(randint) : "0"));
        log.debug("Reply generated = {}", reply.toString());
        break;

      case DCCppConstants.READ_CS_STATUS:
        log.debug("READ_CS_STATUS detected");
        generateReadCSStatusReply(); // Handle this special.
        break;

        /*
               case DCCppConstants.QUERY_SENSOR_STATE:
            // Obsolete ??
            log.debug("QUERY_SENSOR_STATUS detected");
            s = msg.toString();
            try {
        	p = Pattern.compile(DCCppConstants.QUERY_SENSOR_REGEX);
        	m = p.matcher(s);
        	if (!m.matches()) {
        	    log.error("Malformed Sensor Query Command: {}", s);
        	    return(null);
        	}
        	r = "Q " + m.group(1) + " ";
        	// Fake reply: Odd sensors always active, even always inactive.
        	r += ((Integer.parseInt(m.group(1)) % 2) == 1 ? "1" : "0");
        	reply = new DCCppReply(r);
        	log.debug("Reply generated = {}", reply.toString());
            } catch (PatternSyntaxException e) {
        	log.error("Malformed pattern syntax! ");
        	return(null);
            } catch (IllegalStateException e) {
        	log.error("Group called before match operation executed string= " + s);
        	return(null);
            } catch (IndexOutOfBoundsException e) {
        	log.error("Index out of bounds string= " + s);
        	return(null);
            }
            break;
        */
      case DCCppConstants.FUNCTION_CMD:
      case DCCppConstants.ACCESSORY_CMD:
      case DCCppConstants.OPS_WRITE_CV_BYTE:
      case DCCppConstants.OPS_WRITE_CV_BIT:
      case DCCppConstants.WRITE_DCC_PACKET_MAIN:
      case DCCppConstants.WRITE_DCC_PACKET_PROG:
        log.debug("non-reply message detected");
        // Send no reply.
        return (null);

      default:
        return (null);
    }
    return (reply);
  }