/////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2022 Edouard Griffiths, F4EXB // // // // 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 as version 3 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 V3 for more details. // // // // You should have received a copy of the GNU General Public License // // along with this program. If not, see . // /////////////////////////////////////////////////////////////////////////////////// #include #include #include "util/crc.h" #include "m17modax25.h" M17ModAX25::M17ModAX25() : m_ax25Control(3), m_ax25PID(AX25_NO_L3) {} M17ModAX25::~M17ModAX25() {} QByteArray M17ModAX25::makePacket(const QString& callsign, const QString& to, const QString& via, const QString& data) { std::array packet; uint8_t *crc_start; uint8_t *p; crc16x25 crc; uint16_t crcValue; int len; int packet_length; // Create AX.25 packet p = packet.data(); // Unique preamble flag // *p++ = AX25_FLAG; crc_start = p; // Dest p = ax25_address(p, to, 0xe0); // From p = ax25_address(p, callsign, 0x60); // Via p = ax25_address(p, via, 0x61); // Control *p++ = m_ax25Control; // PID *p++ = m_ax25PID; // Data len = data.length(); memcpy(p, data.toUtf8(), len); p += len; // CRC (do not include flags) crc.calculate(crc_start, p-crc_start); crcValue = crc.get(); *p++ = crcValue & 0xff; *p++ = (crcValue >> 8); // Unique postamble flag // *p++ = AX25_FLAG; packet_length = p-&packet[0]; return QByteArray(reinterpret_cast(packet.data()), packet_length); } uint8_t *M17ModAX25::ax25_address(uint8_t *p, QString address, uint8_t crrl) { int len; int i; QByteArray b; uint8_t ssid = 0; bool hyphenSeen = false; len = address.length(); b = address.toUtf8(); ssid = 0; for (i = 0; i < 6; i++) { if ((i < len) && !hyphenSeen) { if (b[i] == '-') { ax25_ssid(b, i, len, ssid); hyphenSeen = true; *p++ = ' ' << 1; } else { *p++ = b[i] << 1; } } else { *p++ = ' ' << 1; } } if (b[i] == '-') { ax25_ssid(b, i, len, ssid); } *p++ = crrl | (ssid << 1); return p; } bool M17ModAX25::ax25_ssid(QByteArray& b, int i, int len, uint8_t& ssid) { if (b[i] == '-') { if (len > i + 1) { ssid = b[i+1] - '0'; if ((len > i + 2) && isdigit(b[i+2])) { ssid = (ssid*10) + (b[i+2] - '0'); } if (ssid >= 16) { qDebug("M17ModAX25::ax25_ssid: ax25_address: SSID greater than 15 not supported"); ssid = ssid & 0xf; return false; } else { return true; } } else { qDebug("M17ModAX25::ax25_ssid: ax25_address: SSID number missing"); return false; } } else { return false; } }