mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-30 20:40:20 -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;
 | |
|     }
 | |
| }
 |