001package jmri.jmrix.sprog; 002 003import java.util.Arrays; 004import jmri.DccLocoAddress; 005import jmri.SpeedStepMode; 006import jmri.NmraPacket; 007import org.slf4j.Logger; 008import org.slf4j.LoggerFactory; 009 010/** 011 * Represent information for a DCC Command Station Queue entry where each entry 012 * is a DCC packet to be transmitted to the rails. 013 * <p> 014 * A SlotListener can be registered to hear of changes in this slot. All changes 015 * in values will result in notification. 016 * <p> 017 * Updated by Andrew Crosland February 2012 to allow slots to hold 28 step speed 018 * packets 019 * 020 * @author Andrew Crosland Copyright (C) 2006, 2012 021 * @author Andrew Berridge 2010 022 */ 023public class SprogSlot { 024 025 private boolean speedPacket = false; 026 private SpeedStepMode speedMode = SpeedStepMode.NMRA_DCC_128; 027 028 public SprogSlot(int num) { 029 payload = new byte[SprogConstants.MAX_PACKET_LENGTH]; 030 payload[0] = 0; 031 payload[1] = 0; 032 payload[2] = 0; 033 f0to4Packet = false; 034 f5to8Packet = false; 035 f9to12Packet = false; 036 f13to20Packet = false; 037 f21to28Packet = false; 038 f29to36Packet = false; 039 f37to44Packet = false; 040 f45to52Packet = false; 041 f53to60Packet = false; 042 f61to68Packet = false; 043 repeat = -1; 044 addr = 0; 045 isLong = false; 046 spd = 0; 047 forward = true; 048 status = SprogConstants.SLOT_FREE; 049 slot = num; 050 opsPkt = false; 051 } 052 053 private byte[] payload; 054 // repeat of -1 is a persistent entry, ie a loco slot 055 private int repeat; 056 private int addr; 057 private boolean isLong; 058 private int spd; 059 private boolean forward; 060 private int status; 061 private final int slot; 062 private boolean opsPkt; 063 064 private boolean f0to4Packet; 065 private boolean f5to8Packet; 066 private boolean f9to12Packet; 067 private boolean f13to20Packet; 068 private boolean f21to28Packet; 069 private boolean f29to36Packet; 070 private boolean f37to44Packet; 071 private boolean f45to52Packet; 072 private boolean f53to60Packet; 073 private boolean f61to68Packet; 074 075 public boolean isF0to4Packet() { 076 return f0to4Packet; 077 } 078 079 public boolean isF5to8Packet() { 080 return f5to8Packet; 081 } 082 083 public boolean isF9to12Packet() { 084 return f9to12Packet; 085 } 086 087 public boolean isF13to20Packet() { 088 return f13to20Packet; 089 } 090 091 public boolean isF21to28Packet() { 092 return f21to28Packet; 093 } 094 095 public boolean isF29to36Packet() { 096 return f29to36Packet; 097 } 098 099 public boolean isF37to44Packet() { 100 return f37to44Packet; 101 } 102 103 public boolean isF45to52Packet() { 104 return f45to52Packet; 105 } 106 107 public boolean isF53to60Packet() { 108 return f53to60Packet; 109 } 110 111 public boolean isF61to68Packet() { 112 return f61to68Packet; 113 } 114 115 private boolean repeatF0 = false; 116 private boolean repeatF1 = false; 117 private boolean repeatF2 = false; 118 private boolean repeatF3 = false; 119 private boolean repeatF4 = false; 120 private boolean repeatF5 = false; 121 private boolean repeatF6 = false; 122 private boolean repeatF7 = false; 123 private boolean repeatF8 = false; 124 private boolean repeatF9 = false; 125 private boolean repeatF10 = false; 126 private boolean repeatF11 = false; 127 private boolean repeatF12 = false; 128 private boolean repeatF13 = false; 129 private boolean repeatF14 = false; 130 private boolean repeatF15 = false; 131 private boolean repeatF16 = false; 132 private boolean repeatF17 = false; 133 private boolean repeatF18 = false; 134 private boolean repeatF19 = false; 135 private boolean repeatF20 = false; 136 private boolean repeatF21 = false; 137 private boolean repeatF22 = false; 138 private boolean repeatF23 = false; 139 private boolean repeatF24 = false; 140 private boolean repeatF25 = false; 141 private boolean repeatF26 = false; 142 private boolean repeatF27 = false; 143 private boolean repeatF28 = false; 144 private boolean repeatF29 = false; 145 private boolean repeatF30 = false; 146 private boolean repeatF31 = false; 147 private boolean repeatF32 = false; 148 private boolean repeatF33 = false; 149 private boolean repeatF34 = false; 150 private boolean repeatF35 = false; 151 private boolean repeatF36 = false; 152 private boolean repeatF37 = false; 153 private boolean repeatF38 = false; 154 private boolean repeatF39 = false; 155 private boolean repeatF40 = false; 156 private boolean repeatF41 = false; 157 private boolean repeatF42 = false; 158 private boolean repeatF43 = false; 159 private boolean repeatF44 = false; 160 private boolean repeatF45 = false; 161 private boolean repeatF46 = false; 162 private boolean repeatF47 = false; 163 private boolean repeatF48 = false; 164 private boolean repeatF49 = false; 165 private boolean repeatF50 = false; 166 private boolean repeatF51 = false; 167 private boolean repeatF52 = false; 168 private boolean repeatF53 = false; 169 private boolean repeatF54 = false; 170 private boolean repeatF55 = false; 171 private boolean repeatF56 = false; 172 private boolean repeatF57 = false; 173 private boolean repeatF58 = false; 174 private boolean repeatF59 = false; 175 private boolean repeatF60 = false; 176 private boolean repeatF61 = false; 177 private boolean repeatF62 = false; 178 private boolean repeatF63 = false; 179 private boolean repeatF64 = false; 180 private boolean repeatF65 = false; 181 private boolean repeatF66 = false; 182 private boolean repeatF67 = false; 183 private boolean repeatF68 = false; 184 185 /** 186 * Set the contents of the slot. Intended for accessory packets. 187 * 188 * @param address int 189 * @param payload byte[] 190 * @param repeat int 191 */ 192 public void set(int address, byte[] payload, int repeat) { 193 addr = address; 194 195 Arrays.copyOf(payload, payload.length); 196 197 this.setRepeat(repeat); 198 status = SprogConstants.SLOT_IN_USE; 199 } 200 201 public void setAccessoryPacket(int address, boolean closed, int repeats) { 202 this.payload = NmraPacket.accDecoderPkt(address, closed); 203 this.addr = address + 10000; 204 this.repeat = repeats; 205 status = SprogConstants.SLOT_IN_USE; 206 } 207 208 public boolean isSpeedPacket() { 209 return speedPacket; 210 } 211 212 public void setSpeed(SpeedStepMode mode, int address, boolean isLongAddress, int speed, boolean forward) { 213 addr = address; 214 isLong = isLongAddress; 215 spd = speed; 216 this.speedPacket = true; 217 this.speedMode = mode; 218 this.f0to4Packet = false; 219 this.f5to8Packet = false; 220 this.f9to12Packet = false; 221 this.f13to20Packet = false; 222 this.f21to28Packet = false; 223 this.f29to36Packet = false; 224 this.f37to44Packet = false; 225 this.f45to52Packet = false; 226 this.f53to60Packet = false; 227 this.f61to68Packet = false; 228 this.forward = forward; 229 if (mode == SpeedStepMode.NMRA_DCC_28) { 230 this.payload = jmri.NmraPacket.speedStep28Packet(true, addr, 231 isLong, spd, forward); 232 } else { 233 this.payload = jmri.NmraPacket.speedStep128Packet(addr, 234 isLong, spd, forward); 235 } 236 status = SprogConstants.SLOT_IN_USE; 237 } 238 239 public void setOps(int address, boolean longAddr, int cv, int val) { 240 payload = NmraPacket.opsCvWriteByte(address, longAddr, cv, val); 241 this.repeat = SprogConstants.OPS_REPEATS; 242 this.opsPkt = true; 243 status = SprogConstants.SLOT_IN_USE; 244 } 245 246 public void f5to8packet(int address, boolean isLongAddress, 247 boolean f5, boolean f5Momentary, 248 boolean f6, boolean f6Momentary, 249 boolean f7, boolean f7Momentary, 250 boolean f8, boolean f8Momentary) { 251 252 this.f5to8Packet = true; 253 this.addr = address; 254 this.isLong = isLongAddress; 255 256 //Were we repeating any functions which we are now not? 257 if ((this.repeatF5 && !f5) 258 || (this.repeatF6 && !f6) 259 || (this.repeatF7 && !f7) 260 || (this.repeatF8 && !f8)) { 261 this.repeat = 3; //Then repeat 3 times 262 } 263 264 this.repeatF5 = !f5Momentary && f5; 265 this.repeatF6 = !f6Momentary && f6; 266 this.repeatF7 = !f7Momentary && f7; 267 this.repeatF8 = !f8Momentary && f8; 268 269 this.payload = jmri.NmraPacket.function5Through8Packet(address, 270 isLongAddress, 271 f5, f6, f7, f8); 272 this.status = SprogConstants.SLOT_IN_USE; 273 274 } 275 276 public void f9to12packet(int address, boolean isLongAddress, 277 boolean f9, boolean f9Momentary, 278 boolean f10, boolean f10Momentary, 279 boolean f11, boolean f11Momentary, 280 boolean f12, boolean f12Momentary) { 281 282 this.f9to12Packet = true; 283 this.addr = address; 284 this.isLong = isLongAddress; 285 286 //Were we repeating any functions which we are now not? 287 if ((this.repeatF9 && !f9) 288 || (this.repeatF10 && !f10) 289 || (this.repeatF11 && !f11) 290 || (this.repeatF12 && !f12)) { 291 this.repeat = 3; //Then repeat 3 times 292 } 293 294 this.repeatF9 = !f9Momentary && f9; 295 this.repeatF10 = !f10Momentary && f10; 296 this.repeatF11 = !f11Momentary && f11; 297 this.repeatF12 = !f12Momentary && f12; 298 299 this.payload = jmri.NmraPacket.function9Through12Packet(address, 300 isLongAddress, 301 f9, f10, f11, f12); 302 this.status = SprogConstants.SLOT_IN_USE; 303 304 } 305 306 public void f13to20packet(int address, boolean isLongAddress, 307 boolean f13, boolean f13Momentary, 308 boolean f14, boolean f14Momentary, 309 boolean f15, boolean f15Momentary, 310 boolean f16, boolean f16Momentary, 311 boolean f17, boolean f17Momentary, 312 boolean f18, boolean f18Momentary, 313 boolean f19, boolean f19Momentary, 314 boolean f20, boolean f20Momentary) { 315 316 this.f13to20Packet = true; 317 this.addr = address; 318 this.isLong = isLongAddress; 319 320 //Were we repeating any functions which we are now not? 321 if ((this.repeatF13 && !f13) 322 || (this.repeatF14 && !f14) 323 || (this.repeatF15 && !f15) 324 || (this.repeatF16 && !f16) 325 || (this.repeatF17 && !f17) 326 || (this.repeatF18 && !f18) 327 || (this.repeatF19 && !f19) 328 || (this.repeatF20 && !f20)) { 329 this.repeat = 3; //Then repeat 3 times 330 } 331 332 this.repeatF13 = !f13Momentary && f13; 333 this.repeatF14 = !f14Momentary && f14; 334 this.repeatF15 = !f15Momentary && f15; 335 this.repeatF16 = !f16Momentary && f16; 336 this.repeatF17 = !f17Momentary && f17; 337 this.repeatF18 = !f18Momentary && f18; 338 this.repeatF19 = !f19Momentary && f19; 339 this.repeatF20 = !f20Momentary && f20; 340 341 this.payload = jmri.NmraPacket.function13Through20Packet(address, 342 isLongAddress, 343 f13, f14, f15, f16, 344 f17, f18, f19, f20); 345 this.status = SprogConstants.SLOT_IN_USE; 346 } 347 348 public void f21to28packet(int address, boolean isLongAddress, 349 boolean f21, boolean f21Momentary, 350 boolean f22, boolean f22Momentary, 351 boolean f23, boolean f23Momentary, 352 boolean f24, boolean f24Momentary, 353 boolean f25, boolean f25Momentary, 354 boolean f26, boolean f26Momentary, 355 boolean f27, boolean f27Momentary, 356 boolean f28, boolean f28Momentary) { 357 358 this.f21to28Packet = true; 359 this.addr = address; 360 this.isLong = isLongAddress; 361 362 //Were we repeating any functions which we are now not? 363 if ((this.repeatF21 && !f21) 364 || (this.repeatF22 && !f22) 365 || (this.repeatF23 && !f23) 366 || (this.repeatF24 && !f24) 367 || (this.repeatF25 && !f25) 368 || (this.repeatF26 && !f26) 369 || (this.repeatF27 && !f27) 370 || (this.repeatF28 && !f28)) { 371 this.repeat = 3; //Then repeat 3 times 372 } 373 374 this.repeatF21 = !f21Momentary && f21; 375 this.repeatF22 = !f22Momentary && f22; 376 this.repeatF23 = !f23Momentary && f23; 377 this.repeatF24 = !f24Momentary && f24; 378 this.repeatF25 = !f25Momentary && f25; 379 this.repeatF26 = !f26Momentary && f26; 380 this.repeatF27 = !f27Momentary && f27; 381 this.repeatF28 = !f28Momentary && f28; 382 383 this.payload = jmri.NmraPacket.function21Through28Packet(address, 384 isLongAddress, 385 f21, f22, f23, f24, 386 f25, f26, f27, f28); 387 this.status = SprogConstants.SLOT_IN_USE; 388 } 389 390 public void f29to36packet(int address, boolean isLongAddress, 391 boolean f29, boolean f29Momentary, 392 boolean f30, boolean f30Momentary, 393 boolean f31, boolean f31Momentary, 394 boolean f32, boolean f32Momentary, 395 boolean f33, boolean f33Momentary, 396 boolean f34, boolean f34Momentary, 397 boolean f35, boolean f35Momentary, 398 boolean f36, boolean f36Momentary) { 399 400 this.f29to36Packet = true; 401 this.addr = address; 402 this.isLong = isLongAddress; 403 404 //Were we repeating any functions which we are now not? 405 if ((this.repeatF29 && !f29) 406 || (this.repeatF30 && !f30) 407 || (this.repeatF31 && !f31) 408 || (this.repeatF32 && !f32) 409 || (this.repeatF33 && !f33) 410 || (this.repeatF34 && !f34) 411 || (this.repeatF35 && !f35) 412 || (this.repeatF36 && !f36)) { 413 this.repeat = 3; //Then repeat 3 times 414 } 415 416 this.repeatF29 = !f29Momentary && f29; 417 this.repeatF30 = !f30Momentary && f30; 418 this.repeatF31 = !f31Momentary && f31; 419 this.repeatF32 = !f32Momentary && f32; 420 this.repeatF33 = !f33Momentary && f33; 421 this.repeatF34 = !f34Momentary && f34; 422 this.repeatF35 = !f35Momentary && f35; 423 this.repeatF36 = !f36Momentary && f36; 424 425 this.payload = jmri.NmraPacket.function29Through36Packet(address, 426 isLongAddress, 427 f29, f30, f31, f32, 428 f33, f34, f35, f36); 429 this.status = SprogConstants.SLOT_IN_USE; 430 } 431 432 public void f37to44packet(int address, boolean isLongAddress, 433 boolean f37, boolean f37Momentary, 434 boolean f38, boolean f38Momentary, 435 boolean f39, boolean f39Momentary, 436 boolean f40, boolean f40Momentary, 437 boolean f41, boolean f41Momentary, 438 boolean f42, boolean f42Momentary, 439 boolean f43, boolean f43Momentary, 440 boolean f44, boolean f44Momentary) { 441 442 this.f37to44Packet = true; 443 this.addr = address; 444 this.isLong = isLongAddress; 445 446 //Were we repeating any functions which we are now not? 447 if ((this.repeatF37 && !f37) 448 || (this.repeatF38 && !f38) 449 || (this.repeatF39 && !f39) 450 || (this.repeatF40 && !f40) 451 || (this.repeatF41 && !f41) 452 || (this.repeatF42 && !f42) 453 || (this.repeatF43 && !f43) 454 || (this.repeatF44 && !f44)) { 455 this.repeat = 3; //Then repeat 3 times 456 } 457 458 this.repeatF37 = !f37Momentary && f37; 459 this.repeatF38 = !f38Momentary && f38; 460 this.repeatF39 = !f39Momentary && f39; 461 this.repeatF40 = !f40Momentary && f40; 462 this.repeatF41 = !f41Momentary && f41; 463 this.repeatF42 = !f42Momentary && f42; 464 this.repeatF43 = !f43Momentary && f43; 465 this.repeatF44 = !f44Momentary && f44; 466 467 this.payload = jmri.NmraPacket.function37Through44Packet(address, 468 isLongAddress, 469 f37, f38, f39, f40, 470 f41, f42, f43, f44); 471 this.status = SprogConstants.SLOT_IN_USE; 472 } 473 474 public void f45to52packet(int address, boolean isLongAddress, 475 boolean f45, boolean f45Momentary, 476 boolean f46, boolean f46Momentary, 477 boolean f47, boolean f47Momentary, 478 boolean f48, boolean f48Momentary, 479 boolean f49, boolean f49Momentary, 480 boolean f50, boolean f50Momentary, 481 boolean f51, boolean f51Momentary, 482 boolean f52, boolean f52Momentary) { 483 484 this.f45to52Packet = true; 485 this.addr = address; 486 this.isLong = isLongAddress; 487 488 //Were we repeating any functions which we are now not? 489 if ((this.repeatF45 && !f45) 490 || (this.repeatF46 && !f46) 491 || (this.repeatF47 && !f47) 492 || (this.repeatF48 && !f48) 493 || (this.repeatF49 && !f49) 494 || (this.repeatF50&& !f50) 495 || (this.repeatF51 && !f51) 496 || (this.repeatF52 && !f52)) { 497 this.repeat = 3; //Then repeat 3 times 498 } 499 500 this.repeatF45 = !f45Momentary && f45; 501 this.repeatF46 = !f46Momentary && f46; 502 this.repeatF47 = !f47Momentary && f47; 503 this.repeatF48 = !f48Momentary && f48; 504 this.repeatF49 = !f49Momentary && f49; 505 this.repeatF50 = !f50Momentary && f50; 506 this.repeatF51 = !f51Momentary && f51; 507 this.repeatF52 = !f52Momentary && f52; 508 509 this.payload = jmri.NmraPacket.function45Through52Packet(address, 510 isLongAddress, 511 f45, f46, f47, f48, 512 f49, f50, f51, f52); 513 this.status = SprogConstants.SLOT_IN_USE; 514 } 515 516 public void f53to60packet(int address, boolean isLongAddress, 517 boolean f53, boolean f53Momentary, 518 boolean f54, boolean f54Momentary, 519 boolean f55, boolean f55Momentary, 520 boolean f56, boolean f56Momentary, 521 boolean f57, boolean f57Momentary, 522 boolean f58, boolean f58Momentary, 523 boolean f59, boolean f59Momentary, 524 boolean f60, boolean f60Momentary) { 525 526 this.f53to60Packet = true; 527 this.addr = address; 528 this.isLong = isLongAddress; 529 530 //Were we repeating any functions which we are now not? 531 if ((this.repeatF53 && !f53) 532 || (this.repeatF54 && !f54) 533 || (this.repeatF55 && !f55) 534 || (this.repeatF56 && !f56) 535 || (this.repeatF57 && !f57) 536 || (this.repeatF58&& !f59) 537 || (this.repeatF59 && !f59) 538 || (this.repeatF60 && !f60)) { 539 this.repeat = 3; //Then repeat 3 times 540 } 541 542 this.repeatF53 = !f53Momentary && f53; 543 this.repeatF54 = !f54Momentary && f54; 544 this.repeatF55 = !f55Momentary && f55; 545 this.repeatF56 = !f56Momentary && f56; 546 this.repeatF57 = !f57Momentary && f57; 547 this.repeatF58 = !f58Momentary && f58; 548 this.repeatF59 = !f59Momentary && f59; 549 this.repeatF60 = !f60Momentary && f60; 550 551 this.payload = jmri.NmraPacket.function53Through60Packet(address, 552 isLongAddress, 553 f53, f54, f55, f56, 554 f57, f58, f59, f60); 555 this.status = SprogConstants.SLOT_IN_USE; 556 } 557 558 public void f61to68packet(int address, boolean isLongAddress, 559 boolean f61, boolean f61Momentary, 560 boolean f62, boolean f62Momentary, 561 boolean f63, boolean f63Momentary, 562 boolean f64, boolean f64Momentary, 563 boolean f65, boolean f65Momentary, 564 boolean f66, boolean f66Momentary, 565 boolean f67, boolean f67Momentary, 566 boolean f68, boolean f68Momentary) { 567 568 this.f61to68Packet = true; 569 this.addr = address; 570 this.isLong = isLongAddress; 571 572 //Were we repeating any functions which we are now not? 573 if ((this.repeatF61 && !f61) 574 || (this.repeatF62 && !f62) 575 || (this.repeatF63 && !f63) 576 || (this.repeatF64 && !f64) 577 || (this.repeatF65 && !f65) 578 || (this.repeatF66&& !f66) 579 || (this.repeatF67 && !f67) 580 || (this.repeatF68 && !f68)) { 581 this.repeat = 3; //Then repeat 3 times 582 } 583 584 this.repeatF61 = !f61Momentary && f61; 585 this.repeatF62 = !f62Momentary && f62; 586 this.repeatF63 = !f63Momentary && f63; 587 this.repeatF64 = !f64Momentary && f64; 588 this.repeatF65 = !f65Momentary && f65; 589 this.repeatF66 = !f66Momentary && f66; 590 this.repeatF67 = !f67Momentary && f67; 591 this.repeatF68 = !f68Momentary && f68; 592 593 this.payload = jmri.NmraPacket.function61Through68Packet(address, 594 isLongAddress, 595 f61, f62, f63, f64, 596 f65, f66, f67, f68); 597 this.status = SprogConstants.SLOT_IN_USE; 598 } 599 600 public void f0to4packet(int address, boolean isLongAddress, 601 boolean f0, boolean f0Momentary, 602 boolean f1, boolean f1Momentary, 603 boolean f2, boolean f2Momentary, 604 boolean f3, boolean f3Momentary, 605 boolean f4, boolean f4Momentary) { 606 607 this.f0to4Packet = true; 608 this.addr = address; 609 this.isLong = isLongAddress; 610 611 //Were we repeating any functions which we are now not? 612 if ((this.repeatF0 && !f0) 613 || (this.repeatF1 && !f1) 614 || (this.repeatF2 && !f2) 615 || (this.repeatF3 && !f3) 616 || (this.repeatF4 && !f4)) { 617 this.repeat = 3; //Then repeat 3 times 618 } 619 620 this.repeatF0 = !f0Momentary && f0; 621 this.repeatF1 = !f1Momentary && f1; 622 this.repeatF2 = !f2Momentary && f2; 623 this.repeatF3 = !f3Momentary && f3; 624 this.repeatF4 = !f4Momentary && f4; 625 626 this.payload = jmri.NmraPacket.function0Through4Packet(address, 627 isLongAddress, 628 f0, f1, f2, f3, f4); 629 this.status = SprogConstants.SLOT_IN_USE; 630 631 } 632 633 public boolean isFinished() { 634 if (this.isF0to4Packet()) { 635 if ((this.repeatF0 || this.repeatF1 || this.repeatF2 || this.repeatF3 || this.repeatF4)) { 636 return false; 637 } 638 } 639 if (this.isF5to8Packet()) { 640 if ((this.repeatF5 || this.repeatF6 || this.repeatF7 || this.repeatF8)) { 641 return false; 642 } 643 } 644 if (this.isF9to12Packet()) { 645 if ((this.repeatF9 || this.repeatF10 || this.repeatF11 || this.repeatF12)) { 646 return false; 647 } 648 } 649 if (this.isF13to20Packet()) { 650 if ((this.repeatF13 || this.repeatF14 || this.repeatF15 || this.repeatF16) 651 || (this.repeatF17 || this.repeatF18 || this.repeatF19 || this.repeatF20)) { 652 return false; 653 } 654 } 655 if (this.isF21to28Packet()) { 656 if ((this.repeatF21 || this.repeatF22 || this.repeatF23 || this.repeatF24) 657 || (this.repeatF25 || this.repeatF26 || this.repeatF27 || this.repeatF28)) { 658 return false; 659 } 660 } 661 if (this.isSpeedPacket() && this.status == SprogConstants.SLOT_IN_USE) { 662 return false; 663 } 664 if (this.repeat > 0 && this.status == SprogConstants.SLOT_IN_USE) { 665 return false; 666 } 667 /* Finished - clear and return true */ 668 this.clear(); 669 return true; 670 } 671 672 public void eStop() { 673 this.setSpeed(this.speedMode, this.addr, this.isLong, 1, this.forward); 674 } 675 676 // Access methods 677 678 public void clear() { 679 status = SprogConstants.SLOT_FREE; 680 addr = 0; 681 spd = 0; 682 speedPacket = false; 683 f0to4Packet = false; 684 f5to8Packet = false; 685 f9to12Packet = false; 686 f13to20Packet = false; 687 f21to28Packet = false; 688 f29to36Packet = false; 689 f37to44Packet = false; 690 f45to52Packet = false; 691 f53to60Packet = false; 692 f61to68Packet = false; 693 if (payload != null) { 694 payload[0] = 0; 695 payload[1] = 0; 696 payload[2] = 0; 697 } 698 opsPkt = false; 699 } 700 701 public boolean isLongAddress() { 702 return isLong; 703 } 704 705 public boolean isFree() { 706 return (status == SprogConstants.SLOT_FREE); 707 } 708 709 public int slotStatus() { 710 return status; 711 } 712 713 public int getRepeat() { 714 return repeat; 715 } 716 717 public void setRepeat(int r) { 718 repeat = r; 719 } 720 721 private int doRepeat() { 722 if (repeat > 0) { 723 log.debug("Slot {} repeats", slot); 724 repeat--; 725 if (repeat == 0) { 726 log.debug("Clear slot {} due to repeats exhausted", slot); 727 this.clear(); 728 } 729 } 730 return repeat; 731 } 732 733 public int speed() { 734 return spd; 735 } 736 737 public int locoAddr() { 738 return addr; 739 } 740 741 public int getAddr() { 742 if (opsPkt == false) { 743 return addr; 744 } else { 745 return addressFromPacket(); 746 } 747 } 748 749 public void setAddr(int a) { 750 addr = a; 751 } 752 753 public boolean getIsLong() { 754 if (opsPkt == false) { 755 return isLong; 756 } else { 757 return ((payload[0] & 0xC0) >= 0xC0); 758 } 759 } 760 761 public void setIsLong(boolean a) { 762 isLong = a; 763 } 764 765 public boolean isForward() { 766 return forward; 767 } 768 769 public boolean isOpsPkt() { 770 return opsPkt; 771 } 772 773 public boolean isActiveAddressMatch(DccLocoAddress address) { 774 return ( status == SprogConstants.SLOT_IN_USE && getAddr() == address.getNumber() && getIsLong() == address.isLongAddress() ); 775 } 776 777 /** 778 * Get the payload of this slot. Note - if this slot has a number of 779 * repeats, calling this method will also decrement the internal repeat 780 * counter. 781 * 782 * @return a byte array containing the payload of this slot 783 */ 784 public byte[] getPayload() { 785 786 byte[] p; 787 if (payload != null) { 788 p = Arrays.copyOf(payload, getPayloadLength());//, a Java 1.6 construct 789 } else { 790 p = new byte[0]; 791 } 792 /*byte [] p = new byte[getPayloadLength()]; 793 for (int i = 0; i<getPayloadLength(); i++) p[i] = payload[i];*/ 794 795 //decrement repeat counter if appropriate 796 doRepeat(); 797 return p; 798 799 } 800 801 public int getSlotNumber() { 802 return slot; 803 } 804 805 private int getPayloadLength() { 806 return this.payload.length; 807 } 808 809 private long lastUpdateTime; // Time of last update for detecting stale slots 810 811 public long getLastUpdateTime() { 812 return lastUpdateTime; 813 } 814 815 /** 816 * Get the address from the packet. 817 * 818 * @return int address from payload 819 */ 820 private int addressFromPacket() { 821 if (isFree()) { 822 return -1; 823 } 824 // First deal with possible extended address 825 if ((payload[0] & 0xC0) == 0xC0) { 826 return ((payload[0] & 0x3F) << 8 | (payload[1] & 0xFF)); 827 } 828 return payload[0]; 829 } 830 831 private final static Logger log = LoggerFactory.getLogger(SprogSlot.class); 832}