mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-31 13:00:26 -04:00 
			
		
		
		
	
		
			
	
	
		
			149 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			149 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
|  | ///////////////////////////////////////////////////////////////////////////////////
 | ||
|  | // 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 <http://www.gnu.org/licenses/>.          //
 | ||
|  | ///////////////////////////////////////////////////////////////////////////////////
 | ||
|  | 
 | ||
|  | #include <QString>
 | ||
|  | #include <array>
 | ||
|  | #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<uint8_t, AX25_MAX_BYTES> 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<const char*>(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; | ||
|  |     } | ||
|  | } |