147 lines
3.1 KiB
C++
147 lines
3.1 KiB
C++
#include "kiss.h"
|
|
|
|
Kiss::Kiss(
|
|
int baud,
|
|
int rxIndicationPin, int txIndicationPin, int rxOnlyPin, int pttPin,
|
|
int lowLevelSelectPin, int rxBufferSize, int txBufferSize
|
|
) {
|
|
_baud = baud;
|
|
_hdlcTnc = new HdlcTnc(
|
|
rxIndicationPin, txIndicationPin, rxOnlyPin, pttPin, lowLevelSelectPin,
|
|
rxBufferSize, txBufferSize
|
|
);
|
|
}
|
|
|
|
void Kiss::begin() {
|
|
Serial.begin(_baud);
|
|
}
|
|
|
|
void Kiss::kissTask() {
|
|
_hdlcTnc->hdlcTask();
|
|
if (Serial.available() > 0) {
|
|
processKissInByte(Serial.read());
|
|
}
|
|
|
|
boolean frameEnd;
|
|
byte rxByte;
|
|
if (_hdlcTnc->getRxByte(&rxByte, &frameEnd)) {
|
|
processKissOutByte(rxByte, frameEnd);
|
|
}
|
|
}
|
|
|
|
void Kiss::processKissOutByte(byte newByte, boolean frameEnd) {
|
|
if (_kissOutFrameEnd) {
|
|
Serial.write(FEND);
|
|
Serial.write(CMD_DATA_FRAME);
|
|
_kissOutFrameEnd = false;
|
|
}
|
|
if (newByte == FEND) {
|
|
Serial.write(FESC);
|
|
Serial.write(TFEND);
|
|
}
|
|
else if (newByte == FESC) {
|
|
Serial.write(FESC);
|
|
Serial.write(TFESC);
|
|
}
|
|
else {
|
|
Serial.write(newByte);
|
|
}
|
|
if (frameEnd) {
|
|
Serial.write(FEND);
|
|
_kissOutFrameEnd = true;
|
|
}
|
|
}
|
|
|
|
void Kiss::processKissInByte(byte newByte) {
|
|
switch (_kissInState) {
|
|
case KS_UNDEF:
|
|
if (newByte == FEND) {
|
|
_kissCommand = CMD_UNDEF;
|
|
_kissInState = KS_GET_CMD;
|
|
}
|
|
break;
|
|
case KS_GET_CMD:
|
|
if (newByte != FEND) {
|
|
if ((newByte < MAX_KISS_CMD) || (newByte > MIN_KISS_CMD)) {
|
|
_kissCommand = newByte;
|
|
_kissInState = KS_GET_DATA;
|
|
}
|
|
else {
|
|
_kissCommand = CMD_UNDEF;
|
|
_kissInState = KS_UNDEF;
|
|
}
|
|
}
|
|
break;
|
|
case KS_GET_DATA:
|
|
if (newByte == FESC) {
|
|
_kissInState = KS_ESCAPE;
|
|
}
|
|
else if (newByte == FEND) {
|
|
sendCommandToTnc();
|
|
_kissCommand = CMD_UNDEF;
|
|
_kissInState = KS_GET_CMD;
|
|
}
|
|
else {
|
|
storeDataByte(newByte);
|
|
}
|
|
break;
|
|
case KS_ESCAPE:
|
|
if (newByte == TFEND) {
|
|
storeDataByte(FEND);
|
|
_kissInState = KS_GET_DATA;
|
|
}
|
|
else if (newByte == TFESC) {
|
|
storeDataByte(FESC);
|
|
_kissInState = KS_GET_DATA;
|
|
}
|
|
else {
|
|
_hdlcTnc->resetTxFrame();
|
|
_kissCommand = CMD_UNDEF;
|
|
_kissInState = KS_UNDEF;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Kiss::storeDataByte(byte newByte) {
|
|
if (_kissCommand == CMD_DATA_FRAME) {
|
|
_hdlcTnc->addByteToTxBuf(newByte);
|
|
}
|
|
else {
|
|
_tncParam = newByte;
|
|
}
|
|
}
|
|
|
|
void Kiss::sendCommandToTnc() {
|
|
switch (_kissCommand) {
|
|
case CMD_DATA_FRAME:
|
|
_hdlcTnc->addFrameEndToTxBuf();
|
|
break;
|
|
case CMD_TX_DELAY:
|
|
_hdlcTnc->setTxDelay(_tncParam * TIME_10_MS_UNITS);
|
|
break;
|
|
case CMD_P:
|
|
_hdlcTnc->setPersistence(_tncParam);
|
|
break;
|
|
case CMD_SLOT_TIME:
|
|
_hdlcTnc->setSlotTime(_tncParam * TIME_10_MS_UNITS);
|
|
break;
|
|
case CMD_TX_TAIL:
|
|
//obsolete
|
|
break;
|
|
case CMD_FULL_DUPLEX:
|
|
_hdlcTnc->setFullDuplex(_tncParam != 0);
|
|
break;
|
|
case CMD_SET_HARDWARE:
|
|
//not implemented
|
|
break;
|
|
case CMD_LOOPBACK_TEST:
|
|
_hdlcTnc->setLoopbackTest(_tncParam > 0);
|
|
break;
|
|
case CMD_RETURN:
|
|
//not implemented
|
|
break;
|
|
}
|
|
}
|
|
|