You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
3.6 KiB

/*
* Copyright (C) 2011-2015,2018 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef IcomController_H
#define IcomController_H
#include "SerialDataController.h"
#include "RingBuffer.h"
#include "Modem.h"
#include "Utils.h"
#include "StdCompat.h"
#include <string>
enum RESP_TYPE_ICOM {
RTI_TIMEOUT,
RTI_ERROR,
RTI_UNKNOWN,
RTI_HEADER,
RTI_DATA,
RTI_EOT,
RTI_HEADER_ACK,
RTI_DATA_ACK,
RTI_PONG
};
/*
* CIcomController - Driver for Icom radios in terminal/access-point mode.
*
* Hardware interface: Serial at 38400 baud with RTS/CTS flow control.
*
* Protocol: Length-prefixed binary frames. The first byte of each frame is
* the payload length; valid lengths are 0x03, 0x04, 0x10, and 0x2C.
* The second byte is the message type:
* 0x03 - PONG (keepalive response)
* 0x10 - D-Star header received (44 bytes payload)
* 0x12 - D-Star data frame received (12 bytes payload)
* bit 6 of byte[3] set = end-of-transmission
* 0x21 - Header ACK/NAK (byte[2] == 0x00 is ACK)
* 0x23 - Data ACK/NAK (byte[2] = sequence, byte[3] == 0x00 is ACK)
*
* Packet counters:
* m_txCounter - monotonically incrementing TX stream ID (rolls at 255 -> 1).
* m_pktCounter - per-packet sequence within a stream, resets on data-sync
* pattern (0x55 0x2D 0x16) or at 21. The radio uses this to
* detect lost frames and request retransmission.
*
* Connection management:
* The driver sends poll frames (0xFF 0xFF 0xFF) initially and ping frames
* (0x02 0x02 0xFF) after the 18th poll. A 5-second lostTimer triggers
* reconnection if no response (PONG or data) is received.
*
* ACK/retry:
* Each transmitted packet is held in storeData until the matching ACK is
* received (matched by sequence number for data frames). A 50ms retryTimer
* re-sends the packet if no ACK arrives. txSpace gates the send queue to
* ensure only one unacknowledged packet is in flight at a time.
*
* getPath() returns an empty string - Icom radios do not use the sysfs USB
* path tracking used by the MMDVM/DV-RPTR family.
*/
class CIcomController : public CModem {
public:
CIcomController(const std::string& port);
virtual ~CIcomController();
virtual bool start();
virtual unsigned int getSpace();
virtual bool isTXReady();
virtual bool writeHeader(const CHeaderData& header);
virtual bool writeData(const unsigned char* data, unsigned int length, bool end);
virtual std::string getPath() const;
private:
void entry();
std::string m_port;
CSerialDataController m_serial;
CRingBuffer<unsigned char> m_txData;
unsigned char m_txCounter;
unsigned char m_pktCounter;
RESP_TYPE_ICOM getResponse(unsigned char* buffer, unsigned int& length);
// Sends 0xFF 0xFF 0xFF - null keepalive before the radio responds to pings.
bool writePoll();
// Sends 0x02 0x02 0xFF - ping request; elicits a PONG response from the radio.
bool writePing();
};
#endif

Powered by TurnKey Linux.