void runBinaryProtocolLoop(ts_channel_s *tsChannel, bool_t isConsoleRedirect) { int wasReady = false; while (true) { int isReady = ts_serial_ready(isConsoleRedirect); if (!isReady) { chThdSleepMilliseconds(10); wasReady = false; continue; } if (!wasReady) { wasReady = true; // scheduleSimpleMsg(&logger, "ts channel is now ready ", hTimeNow()); } tsState.tsCounter++; int recieved = chnReadTimeout(tsChannel->channel, &firstByte, 1, TS_READ_TIMEOUT); if (recieved != 1) { // tunerStudioError("ERROR: no command"); continue; } // scheduleMsg(logger, "Got first=%x=[%c]", firstByte, firstByte); if (handlePlainCommand(tsChannel, firstByte)) continue; recieved = chnReadTimeout(tsChannel->channel, &secondByte, 1, TS_READ_TIMEOUT); if (recieved != 1) { tunerStudioError("ERROR: no second"); continue; } // scheduleMsg(logger, "Got secondByte=%x=[%c]", secondByte, secondByte); uint32_t incomingPacketSize = firstByte * 256 + secondByte; if (incomingPacketSize == BINARY_SWITCH_TAG) { // we are here if we get a binary switch request while already in binary mode. We will just ignore it. tunerStudioWriteData(tsChannel, (const uint8_t *) &BINARY_RESPONSE, 2); continue; } if (incomingPacketSize == 0 || incomingPacketSize > (sizeof(tsChannel->crcReadBuffer) - CRC_WRAPPING_SIZE)) { scheduleMsg(&tsLogger, "TunerStudio: invalid size: %d", incomingPacketSize); tunerStudioError("ERROR: CRC header size"); sendErrorCode(tsChannel); continue; } recieved = chnReadTimeout(tsChannel->channel, (uint8_t* )tsChannel->crcReadBuffer, 1, TS_READ_TIMEOUT); if (recieved != 1) { tunerStudioError("ERROR: did not receive command"); continue; } char command = tsChannel->crcReadBuffer[0]; if (!isKnownCommand(command)) { scheduleMsg(&tsLogger, "unexpected command %x", command); sendErrorCode(tsChannel); continue; } // scheduleMsg(logger, "TunerStudio: reading %d+4 bytes(s)", incomingPacketSize); recieved = chnReadTimeout(tsChannel->channel, (uint8_t * ) (tsChannel->crcReadBuffer + 1), incomingPacketSize + CRC_VALUE_SIZE - 1, TS_READ_TIMEOUT); int expectedSize = incomingPacketSize + CRC_VALUE_SIZE - 1; if (recieved != expectedSize) { scheduleMsg(&tsLogger, "got ONLY %d for packet size %d/%d for command %c", recieved, incomingPacketSize, expectedSize, command); tunerStudioError("ERROR: not enough"); continue; } uint32_t expectedCrc = *(uint32_t*) (tsChannel->crcReadBuffer + incomingPacketSize); expectedCrc = SWAP_UINT32(expectedCrc); uint32_t actualCrc = crc32(tsChannel->crcReadBuffer, incomingPacketSize); if (actualCrc != expectedCrc) { scheduleMsg(&tsLogger, "TunerStudio: CRC %x %x %x %x", tsChannel->crcReadBuffer[incomingPacketSize + 0], tsChannel->crcReadBuffer[incomingPacketSize + 1], tsChannel->crcReadBuffer[incomingPacketSize + 2], tsChannel->crcReadBuffer[incomingPacketSize + 3]); scheduleMsg(&tsLogger, "TunerStudio: command %c actual CRC %x/expected %x", tsChannel->crcReadBuffer[0], actualCrc, expectedCrc); tunerStudioError("ERROR: CRC issue"); continue; } // scheduleMsg(logger, "TunerStudio: P00-07 %x %x %x %x %x %x %x %x", crcIoBuffer[0], crcIoBuffer[1], // crcIoBuffer[2], crcIoBuffer[3], crcIoBuffer[4], crcIoBuffer[5], crcIoBuffer[6], crcIoBuffer[7]); int success = tunerStudioHandleCrcCommand(tsChannel, tsChannel->crcReadBuffer, incomingPacketSize); if (!success) print("got unexpected TunerStudio command %x:%c\r\n", command, command); } }
static msg_t tsThreadEntryPoint(void *arg) { (void) arg; chRegSetThreadName("tunerstudio thread"); int wasReady = false; while (true) { int isReady = ts_serail_ready(); if (!isReady) { chThdSleepMilliseconds(10); wasReady = false; continue; } if (!wasReady) { wasReady = TRUE; // scheduleSimpleMsg(&logger, "ts channel is now ready ", hTimeNow()); } tsCounter++; int recieved = chSequentialStreamRead(getTsSerialDevice(), &firstByte, 1); if (recieved != 1) { tunerStudioError("ERROR: no command"); continue; } // scheduleMsg(&logger, "Got first=%x=[%c]", firstByte, firstByte); if (handlePlainCommand(firstByte)) continue; recieved = chSequentialStreamRead(getTsSerialDevice(), &secondByte, 1); if (recieved != 1) { tunerStudioError("ERROR: no second"); continue; } // scheduleMsg(&logger, "Got secondByte=%x=[%c]", secondByte, secondByte); uint32_t incomingPacketSize = firstByte * 256 + secondByte; if (incomingPacketSize == 0 || incomingPacketSize > (sizeof(crcIoBuffer) - CRC_WRAPPING_SIZE)) { scheduleMsg(&logger, "TunerStudio: invalid size: %d", incomingPacketSize); tunerStudioError("ERROR: size"); sendErrorCode(); continue; } recieved = chnReadTimeout(getTsSerialDevice(), crcIoBuffer, 1, MS2ST(TS_READ_TIMEOUT)); if (recieved != 1) { tunerStudioError("ERROR: did not receive command"); continue; } char command = crcIoBuffer[0]; if (!isKnownCommand(command)) { scheduleMsg(&logger, "unexpected command %x", command); sendErrorCode(); continue; } // scheduleMsg(&logger, "TunerStudio: reading %d+4 bytes(s)", incomingPacketSize); recieved = chnReadTimeout(getTsSerialDevice(), (uint8_t * ) (crcIoBuffer + 1), incomingPacketSize + CRC_VALUE_SIZE - 1, MS2ST(TS_READ_TIMEOUT)); int expectedSize = incomingPacketSize + CRC_VALUE_SIZE - 1; if (recieved != expectedSize) { scheduleMsg(&logger, "got ONLY %d for packet size %d/%d for command %c", recieved, incomingPacketSize, expectedSize, command); tunerStudioError("ERROR: not enough"); continue; } uint32_t expectedCrc = *(uint32_t*) (crcIoBuffer + incomingPacketSize); expectedCrc = SWAP_UINT32(expectedCrc); uint32_t actualCrc = crc32(crcIoBuffer, incomingPacketSize); if (actualCrc != expectedCrc) { scheduleMsg(&logger, "TunerStudio: CRC %x %x %x %x", crcIoBuffer[incomingPacketSize + 0], crcIoBuffer[incomingPacketSize + 1], crcIoBuffer[incomingPacketSize + 2], crcIoBuffer[incomingPacketSize + 3]); scheduleMsg(&logger, "TunerStudio: command %c actual CRC %x/expected %x", crcIoBuffer[0], actualCrc, expectedCrc); tunerStudioError("ERROR: CRC issue"); continue; } // scheduleMsg(&logger, "TunerStudio: P00-07 %x %x %x %x %x %x %x %x", crcIoBuffer[0], crcIoBuffer[1], // crcIoBuffer[2], crcIoBuffer[3], crcIoBuffer[4], crcIoBuffer[5], crcIoBuffer[6], crcIoBuffer[7]); int success = tunerStudioHandleCrcCommand(crcIoBuffer, incomingPacketSize); if (!success) print("got unexpected TunerStudio command %x:%c\r\n", command, command); } #if defined __GNUC__ return 0; #endif }