| 577 | } |
| 578 | |
| 579 | void doRemoteCommand(txMachine *the, uint8_t *cmd, uint32_t cmdLen) |
| 580 | { |
| 581 | uint16_t resultID = 0; |
| 582 | int16_t resultCode = 0; |
| 583 | uint8_t cmdID; |
| 584 | int baud = 0; |
| 585 | |
| 586 | if (!cmdLen) |
| 587 | return; |
| 588 | |
| 589 | cmdID = *cmd++; |
| 590 | cmdLen -= 1; |
| 591 | |
| 592 | if (cmdLen >= 2) { |
| 593 | resultID = (cmd[0] << 8) | cmd[1]; |
| 594 | cmd += 2, cmdLen -= 2; |
| 595 | |
| 596 | the->echoBuffer[0] = 5; |
| 597 | the->echoBuffer[1] = resultID >> 8; |
| 598 | the->echoBuffer[2] = resultID & 0xff; |
| 599 | the->echoBuffer[3] = 0; |
| 600 | the->echoBuffer[4] = 0; |
| 601 | the->echoOffset = 5; |
| 602 | } |
| 603 | |
| 604 | switch (cmdID) { |
| 605 | case 1: // restart |
| 606 | the->wsState = 18; |
| 607 | break; |
| 608 | |
| 609 | #if MODDEF_XS_MODS |
| 610 | case 2: { // uninstall |
| 611 | uint8_t erase[16] = {0}; |
| 612 | uint32_t offset = (uintptr_t)kModulesStart - (uintptr_t)kFlashStart; |
| 613 | if (!modSPIWrite(offset, sizeof(erase), erase)) |
| 614 | resultCode = -2; |
| 615 | } break; |
| 616 | |
| 617 | case 3: { // install some |
| 618 | uint32_t offset = c_read32be(cmd); |
| 619 | cmd += 4, cmdLen -= 4; |
| 620 | if ((offset + cmdLen) > kModulesByteLength) { |
| 621 | resultCode = -3; |
| 622 | break; |
| 623 | } |
| 624 | |
| 625 | offset += (uintptr_t)kModulesStart - (uintptr_t)kFlashStart; |
| 626 | |
| 627 | int firstSector = offset / kFlashSectorSize, lastSector = (offset + cmdLen) / kFlashSectorSize; |
| 628 | if (!(offset % kFlashSectorSize)) // starts on sector boundary |
| 629 | modSPIErase(offset, kFlashSectorSize * ((lastSector - firstSector) + 1)); |
| 630 | else if (firstSector != lastSector) |
| 631 | modSPIErase((firstSector + 1) * kFlashSectorSize, kFlashSectorSize * (lastSector - firstSector)); // crosses into a new sector |
| 632 | |
| 633 | if (!modSPIWrite(offset, cmdLen, cmd)) { |
| 634 | resultCode = -1; |
| 635 | } |
| 636 | } // end of case 3 |
no test coverage detected